Welcome to Subscribe On Youtube
Formatted question description: https://leetcode.ca/all/798.html
798. Smallest Rotation with Highest Score
Level
Hard
Description
Given an array A
, we may rotate it by a nonnegative integer K
so that the array becomes A[K], A[K+1], A{K+2], ... A[A.length  1], A[0], A[1], ..., A[K1]
. 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 most20000
.A[i]
will be in the range[0, A.length]
.
Solution
For index i
, if the rotation index K
is between i  A[i] + 1
and i
(both are mod A.length
), then A[i]
will have no points. Create an array points
of length A.length
. For each index i
, subtract 1 from points[i  A[i] + 1]
and add 1 to points[i + 1]
. Then loop over points
and calculate the sums of each prefix. If a prefix sum is the greatest, then update the maximum sum and the corresponding index. Finally, return the index.

class Solution { public int bestRotation(int[] A) { int length = A.length; int[] points = new int[length]; for (int i = 0; i < length; i++) { int low = (i  A[i] + 1 + length) % length; int high = (i + 1) % length; points[low]; points[high]++; if (low > high) points[0]; } int maxIndex = 0; int maxScore = length; int curScore = 0; for (int i = 0; i < length; i++) { curScore += points[i]; if (curScore > maxScore) { maxIndex = i; maxScore = curScore; } } return maxIndex; } }

class Solution: def bestRotation(self, nums: List[int]) > int: n = len(nums) mx, ans = 1, n d = [0] * n for i, v in enumerate(nums): l, r = (i + 1) % n, (n + i + 1  v) % n d[l] += 1 d[r] = 1 s = 0 for k, t in enumerate(d): s += t if s > mx: mx = s ans = k return ans

class Solution { public: int bestRotation(vector<int>& nums) { int n = nums.size(); int mx = 1, ans = n; vector<int> d(n); for (int i = 0; i < n; ++i) { int l = (i + 1) % n; int r = (n + i + 1  nums[i]) % n; ++d[l]; d[r]; } int s = 0; for (int k = 0; k < n; ++k) { s += d[k]; if (s > mx) { mx = s; ans = k; } } return ans; } };

func bestRotation(nums []int) int { n := len(nums) d := make([]int, n) for i, v := range nums { l, r := (i+1)%n, (n+i+1v)%n d[l]++ d[r] } mx, ans, s := 1, n, 0 for k, t := range d { s += t if s > mx { mx = s ans = k } } return ans }