75th LeetCode Weekly Contest Smallest Rotation with Highest Score

Given an array A, we may rotate it by a non-negative integer K so that the array becomes A[K], A[K+1], A{K+2], ... A[A.length - 1], A[0], A[1], ..., A[K-1].  Afterward, any entries that are less than or equal to their index are worth 1 point. 

For example, if we have [2, 4, 1, 3, 0], and we rotate by K = 2, it becomes [1, 3, 0, 2, 4].  This is worth 3 points because 1 > 0 [no points], 3 > 1 [no points], 0 <= 2 [one point], 2 <= 3 [one point], 4 <= 4 [one point].

Over all possible rotations, return the rotation index K that corresponds to the highest score we could receive.  If there are multiple answers, return the smallest such index K.

Example 1:
Input: [2, 3, 1, 4, 0]
Output: 3
Explanation:  
Scores for each K are listed below: 
K = 0,  A = [2,3,1,4,0],    score 2
K = 1,  A = [3,1,4,0,2],    score 3
K = 2,  A = [1,4,0,2,3],    score 3
K = 3,  A = [4,0,2,3,1],    score 4
K = 4,  A = [0,2,3,1,4],    score 3

So we should choose K = 3, which has the highest score.

Example 2:
Input: [1, 3, 0, 2, 4]
Output: 0
Explanation:  A will always have 3 points no matter how it shifts.
So we will choose the smallest K, which is 0.

Note:

  • A will have length at most 20000.
  • A[i] will be in the range [0, A.length].

题意很简单,如果简单想的话,其实有个n^2的解法,就是每个数字都算它能够加分的部分,然后存起来把分数最大的那个拿出来就好了

但对于初始位置,我们也可以知道对于这个数字的移动范围,比如a[5]=2,那么这位置上的2,可以移动5-2=3个位置不会减分。。

这里知道的是,如果移动i个位置,那么范围在i-1的数字将失去得分,变为0。

那么把a[4]放到最后一个位置呢?我们需要判断一下就好了,处理完毕之后,毕竟把a[4]放在最后一位,我们又要计算一次移动范围。

class Solution:
    def bestRotation(self, A):
        """
        :type A: List[int]
        :rtype: int
        """
        List= [0 for x in range(len(A)*3)]
        sum = 0
        Len = len(A)
        for i in range(Len):
            if i>=A[i]:
                List[i-A[i]]=List[i-A[i]]+1 #i-ans表示可以移动的范围
                sum=sum+1
        Max = sum
        tag = 0
        for i in range(1,Len):
            sum=sum-List[i-1]#每次移动i个元素,那么i-1范围的将无法符合要求
            List[i-1] = 0
            ans=A[i-1]-(Len-1)
            if ans<=0:
                sum=sum+1
            List[i-ans]=List[i-ans]+1
            if Max<sum:
                Max=sum
                tag=i
        
        return tag
            
            
        
            
int bestRotation(int* A, int ASize) {
    int* rotationPoint = calloc(ASize, sizeof(int));
    for (int i = 0; i < ASize; ++i) {
        int target = A[i];
        for (int k = 0; k < ASize; ++k) {
            if ((i >= k && target <= i - k) || (i < k && target <= ASize - k + i))
                rotationPoint[k]++;
        }
    }
    int max = -1, k;
    for (int i = 0; i < ASize; ++i) {
        if (rotationPoint[i] > max) {
            max = rotationPoint[i];
            k = i;
        }
    }
    free(rotationPoint);
    return k;
}
原文地址:https://www.cnblogs.com/yinghualuowu/p/8577546.html