Smallest Rotation with Highest Score

Hard
#0752Time: O(N^2), where N is the length of `nums`. The outer loop runs N times for each possible rotation `k`, and the inner loop also runs N times to calculate the score for that rotation.Space: O(1) extra space, as we only need a few variables to store the current state (scores and best k).
Patterns
Data structures

Prompt

You are given an array nums. You can rotate it by a non-negative integer k so that the array becomes [nums[k], nums[k + 1], ... nums[nums.length - 1], nums[0], nums[1], ..., nums[k-1]]. Afterward, any entries that are less than or equal to their index are worth one point.

  • For example, if we have nums = [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].

Return the rotation index k that corresponds to the highest score we can achieve if we rotated nums by it. If there are multiple answers, return the smallest such index k.

 

Example 1:

Input: nums = [2,3,1,4,0]
Output: 3
Explanation: Scores for each k are listed below: 
k = 0,  nums = [2,3,1,4,0],    score 2
k = 1,  nums = [3,1,4,0,2],    score 3
k = 2,  nums = [1,4,0,2,3],    score 3
k = 3,  nums = [4,0,2,3,1],    score 4
k = 4,  nums = [0,2,3,1,4],    score 3
So we should choose k = 3, which has the highest score.

Example 2:

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

 

Constraints:

  • 1 <= nums.length <= 105
  • 0 <= nums[i] < nums.length

Approaches

2 approaches with complexity analysis and trade-offs.

This approach directly simulates the process described in the problem. We test every possible rotation k from 0 to N-1. For each rotation, we calculate its score by iterating through the conceptually rotated array and counting how many elements A[i] satisfy the condition A[i] <= i. We maintain a variable to track the highest score seen so far and the corresponding rotation index k. Since we iterate k from 0 upwards and only update the result for strictly greater scores, we are guaranteed to find the smallest k in case of a tie.

Algorithm

  1. Initialize maxScore to -1 and bestK to 0.
  2. Iterate through each possible rotation index k from 0 to N-1, where N is the length of the array.
  3. For each k, initialize a currentScore to 0.
  4. Iterate through each index i from 0 to N-1 of the (conceptually) rotated array.
  5. The element at index i in the array rotated by k is nums[(i + k) % N].
  6. Check if this element's value is less than or equal to its new index: nums[(i + k) % N] <= i.
  7. If the condition is true, increment currentScore.
  8. After iterating through all i's, compare currentScore with maxScore.
  9. If currentScore > maxScore, update maxScore = currentScore and bestK = k.
  10. After the outer loop finishes, bestK will hold the smallest rotation index with the highest score. Return bestK.

Walkthrough

The brute-force method involves a straightforward simulation. We use two nested loops. The outer loop iterates through all possible rotation values k, from 0 to N-1. The inner loop calculates the score for that specific rotation k. To find the value at a new index i after rotating by k, we can map it back to the original array. An element at new index i was originally at index (i + k) % N. We check if nums[(i + k) % N] <= i. We sum up the points for a given k and compare it with the maximum score found so far. This process is repeated for all k, and the k that yields the highest score is the answer.

class Solution {    public int bestRotation(int[] nums) {        int n = nums.length;        int maxScore = -1;        int bestK = 0;         for (int k = 0; k < n; k++) {            int currentScore = 0;            for (int i = 0; i < n; i++) {                // The original index of the element at new index i is (i + k) % n                int originalIndex = (i + k) % n;                if (nums[originalIndex] <= i) {                    currentScore++;                }            }            if (currentScore > maxScore) {                maxScore = currentScore;                bestK = k;            }        }        return bestK;    }}

Complexity

Time

O(N^2), where N is the length of `nums`. The outer loop runs N times for each possible rotation `k`, and the inner loop also runs N times to calculate the score for that rotation.

Space

O(1) extra space, as we only need a few variables to store the current state (scores and best k).

Trade-offs

Pros

  • Simple to understand and implement.

  • Requires no extra space other than a few variables.

Cons

  • Highly inefficient due to its nested loops.

  • Will result in a 'Time Limit Exceeded' (TLE) error for large input sizes as specified in the constraints.

Solutions

class Solution {public  int bestRotation(int[] nums) {    int n = nums.length;    int[] d = new int[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 mx = -1;    int s = 0;    int ans = n;    for (int k = 0; k < n; ++k) {      s += d[k];      if (s > mx) {        mx = s;        ans = k;      }    }    return ans;  }}

Video walkthrough

Newsletter

One sharp idea, every week

System design and interview prep — short enough to finish.

No spam. Unsubscribe anytime.

Practice

Same difficulty — related problems to reinforce the pattern.