Smallest Rotation with Highest Score

hard arrays difference-array prefix-sum

Problem

Given array nums of length n, you choose a rotation k. After rotating left by k, index i scores 1 if nums[i] <= i. Return the k that maximizes total score, choosing the smallest k on ties.

Inputnums = [2,3,1,4,0]
Output3
Rotating by 3 gives scoring at positions 0,1,2,3 — total 3.

def bestRotation(nums):
    n = len(nums)
    diff = [0] * (n + 1)
    for j, v in enumerate(nums):
        lo = (j - (n - 1)) % n
        hi = (j - v) % n
        if lo <= hi:
            diff[lo] += 1
            diff[hi + 1] -= 1
        else:
            diff[lo] += 1
            diff[n] -= 1
            diff[0] += 1
            diff[hi + 1] -= 1
    best_k, best_score, cur = 0, -1, 0
    for k in range(n):
        cur += diff[k]
        if cur > best_score:
            best_score, best_k = cur, k
    return best_k
var bestRotation = function(nums) {
    const n = nums.length;
    const diff = new Array(n + 1).fill(0);
    for (let j = 0; j < n; j++) {
        const v = nums[j];
        const lo = ((j - (n - 1)) % n + n) % n;
        const hi = ((j - v) % n + n) % n;
        if (lo <= hi) { diff[lo] += 1; diff[hi + 1] -= 1; }
        else { diff[lo] += 1; diff[n] -= 1; diff[0] += 1; diff[hi + 1] -= 1; }
    }
    let bestK = 0, bestScore = -1, cur = 0;
    for (let k = 0; k < n; k++) {
        cur += diff[k];
        if (cur > bestScore) { bestScore = cur; bestK = k; }
    }
    return bestK;
};
class Solution {
    public int bestRotation(int[] nums) {
        int n = nums.length;
        int[] diff = new int[n + 1];
        for (int j = 0; j < n; j++) {
            int v = nums[j];
            int lo = ((j - (n - 1)) % n + n) % n;
            int hi = ((j - v) % n + n) % n;
            if (lo <= hi) { diff[lo]++; diff[hi + 1]--; }
            else { diff[lo]++; diff[n]--; diff[0]++; diff[hi + 1]--; }
        }
        int bestK = 0, bestScore = -1, cur = 0;
        for (int k = 0; k < n; k++) {
            cur += diff[k];
            if (cur > bestScore) { bestScore = cur; bestK = k; }
        }
        return bestK;
    }
}
class Solution {
public:
    int bestRotation(vector<int>& nums) {
        int n = nums.size();
        vector<int> diff(n + 1, 0);
        for (int j = 0; j < n; j++) {
            int v = nums[j];
            int lo = ((j - (n - 1)) % n + n) % n;
            int hi = ((j - v) % n + n) % n;
            if (lo <= hi) { diff[lo]++; diff[hi + 1]--; }
            else { diff[lo]++; diff[n]--; diff[0]++; diff[hi + 1]--; }
        }
        int bestK = 0, bestScore = -1, cur = 0;
        for (int k = 0; k < n; k++) {
            cur += diff[k];
            if (cur > bestScore) { bestScore = cur; bestK = k; }
        }
        return bestK;
    }
};
Time: O(n) Space: O(n)