array
intervals
bst
accumulate
]
Leetcode 0798 Smallest Rotation with Highest Score
Problem statement
https://leetcode.com/problems/smallest-rotation-with-highest-score/
Solution 1
One solution is to use SortedList: on the first moment of time we need to check how many elements there in [A[i] - i] such that they are <= 0. When we need have numbers [A[i] - i + 1] and we need to find how many of them <= 0, which is equivalent to find how many numbers from [A[i] - i] are <= -1 where we updated one element A[0] -> A[0] - n. Then we do it again and again.
Complexity
Time complexity is O(n log n), space is O(n).
Code
from sortedcontainers import SortedList
class Solution:
def bestRotation(self, A):
B = [a - i for i,a in enumerate(A)]
n, ans, SList = len(A), (0, -1), SortedList(B)
for i in range(n):
ans = max(ans, (SortedList.bisect(SList, -i), -i))
SList.remove(B[i])
SList.add(B[i]-n)
return -ans[1]
Solution 2
There is also O(n) smart solution, using intervals: note, that for every number A[i] there will be continuous interval of K for which it will give us a point (or continuous but with transition n-1 -> 0). So, now we have the following problem: we have several intervals and we need to find the first index with maximum number of overlappings. We can find that for i-th point interval will be [(i+1)\%n, (i-A[i])\%n], so we use trick with cumulative sums: for [a, b] we increase a-th element by 1 and decrease (b+1)-th element by one.
Complexity
It is O(n) for time and space.
Code
class Solution:
def bestRotation(self, A):
n = len(A)
good = [0]*n
for i in range(n):
beg, end = (i+1)%n, (i-A[i]+1)%n
good[end] -= 1
good[beg] += 1
t = list(accumulate(good))
return t.index(max(t))
Remark
Moreover, it is not really necessary to update beg on each iteration: it will be updated exactly $n$ times for each position, so we can start with good = [1]*n.