LeetCode 2612. Minimum Reverse Operations Solution in Java, C++, Python & More | Explanation + Code

CoderIndeed
0
2612. Minimum Reverse Operations

Description

You are given an integer n and an integer p representing an array arr of length n where all elements are set to 0's, except position p which is set to 1. You are also given an integer array banned containing restricted positions. Perform the following operation on arr:

  • Reverse a subarray with size k if the single 1 is not set to a position in banned.

Return an integer array answer with n results where the ith result is the minimum number of operations needed to bring the single 1 to position i in arr, or -1 if it is impossible.

 

Example 1:

Input: n = 4, p = 0, banned = [1,2], k = 4

Output: [0,-1,-1,1]

Explanation:

  • Initially 1 is placed at position 0 so the number of operations we need for position 0 is 0.
  • We can never place 1 on the banned positions, so the answer for positions 1 and 2 is -1.
  • Perform the operation of size 4 to reverse the whole array.
  • After a single operation 1 is at position 3 so the answer for position 3 is 1.

Example 2:

Input: n = 5, p = 0, banned = [2,4], k = 3

Output: [0,-1,-1,-1,-1]

Explanation:

  • Initially 1 is placed at position 0 so the number of operations we need for position 0 is 0.
  • We cannot perform the operation on the subarray positions [0, 2] because position 2 is in banned.
  • Because 1 cannot be set at position 2, it is impossible to set 1 at other positions in more operations.

Example 3:

Input: n = 4, p = 2, banned = [0,1,3], k = 1

Output: [-1,-1,0,-1]

Explanation:

Perform operations of size 1 and 1 never changes its position.

 

Constraints:

  • 1 <= n <= 105
  • 0 <= p <= n - 1
  • 0 <= banned.length <= n - 1
  • 0 <= banned[i] <= n - 1
  • 1 <= k <= n 
  • banned[i] != p
  • all values in banned are unique 

Solutions

Solution 1: Ordered Set + BFS

We notice that for any index i in the subarray interval [l,..r], the flipped index j = l + r - i.

If the subarray moves one position to the right, then j = l + 1 + r + 1 - i = l + r - i + 2, that is, j will increase by 2.

Similarly, if the subarray moves one position to the left, then j = l - 1 + r - 1 - i = l + r - i - 2, that is, j will decrease by 2.

Therefore, for a specific index i, all its flipped indices form an arithmetic progression with common difference 2, that is, all the flipped indices have the same parity.

Next, we consider the range of values ​​of the index i after flipping j.

  • If the boundary is not considered, the range of values ​​of j is [i - k + 1, i + k - 1].
  • If the subarray is on the left, then [l, r] = [0, k - 1], so the flipped index j of i is 0 + k - 1 - i, that is, j = k - i - 1, so the left boundary mi = max(i - k + 1, k - i - 1).
  • If the subarray is on the right, then [l, r] = [n - k, n - 1], so the flipped index j= n - k + n - 1 - i is j = n × 2 - k - i - 1, so the right boundary of j is mx = min(i + k - 1, n × 2 - k - i - 1).

We use two ordered sets to store all the odd indices and even indices to be searched, here we need to exclude the indices in the array banned and the index p.

Then we use BFS to search, each time searching all the flipped indices j of the current index i, that is, j = mi, mi + 2, mi + 4, \dots, mx, updating the answer of index j and adding index j to the search queue, and removing index j from the corresponding ordered set.

When the search is over, the answer to all indices can be obtained.

The time complexity is O(n × log n) and the space complexity is O(n). Where n is the given array length in the problem.

PythonJavaC++GoTypeScriptRust
class Solution: def minReverseOperations( self, n: int, p: int, banned: List[int], k: int ) -> List[int]: ans = [-1] * n ans[p] = 0 ts = [SortedSet() for _ in range(2)] for i in range(n): ts[i % 2].add(i) ts[p % 2].remove(p) for i in banned: ts[i % 2].remove(i) ts[0].add(n) ts[1].add(n) q = deque([p]) while q: i = q.popleft() mi = max(i - k + 1, k - i - 1) mx = min(i + k - 1, n * 2 - k - i - 1) s = ts[mi % 2] j = s.bisect_left(mi) while s[j] <= mx: q.append(s[j]) ans[s[j]] = ans[i] + 1 s.remove(s[j]) j = s.bisect_left(mi) return ans(code-box)

Post a Comment

0Comments

Post a Comment (0)

#buttons=(Accept !) #days=(20)

Our website uses cookies to enhance your experience. Check Now
Accept !