Welcome to Subscribe On Youtube
3510. Minimum Pair Removal to Sort Array II
Description
Given an array nums, you can perform the following operation any number of times:
- Select the adjacent pair with the minimum sum in
nums. If multiple such pairs exist, choose the leftmost one. - Replace the pair with their sum.
Return the minimum number of operations needed to make the array non-decreasing.
An array is said to be non-decreasing if each element is greater than or equal to its previous element (if it exists).
Example 1:
Input: nums = [5,2,3,1]
Output: 2
Explanation:
- The pair
(3,1)has the minimum sum of 4. After replacement,nums = [5,2,4]. - The pair
(2,4)has the minimum sum of 6. After replacement,nums = [5,6].
The array nums became non-decreasing in two operations.
Example 2:
Input: nums = [1,2,2]
Output: 0
Explanation:
The array nums is already sorted.
Constraints:
1 <= nums.length <= 105-109 <= nums[i] <= 109
Solutions
Solution 1
-
class Solution { record Pair(long s, int i) implements Comparable<Pair> { @Override public int compareTo(Pair other) { int compareS = Long.compare(this.s, other.s); return compareS != 0 ? compareS : Integer.compare(this.i, other.i); } } public int minimumPairRemoval(int[] nums) { int n = nums.length; int inv = 0; TreeSet<Pair> sl = new TreeSet<>(); for (int i = 0; i < n - 1; ++i) { if (nums[i] > nums[i + 1]) { ++inv; } sl.add(new Pair(nums[i] + nums[i + 1], i)); } TreeSet<Integer> idx = new TreeSet<>(); long[] arr = new long[n]; for (int i = 0; i < n; ++i) { idx.add(i); arr[i] = nums[i]; } int ans = 0; while (inv > 0) { ++ans; var p = sl.pollFirst(); long s = p.s; int i = p.i; int j = idx.higher(i); if (arr[i] > arr[j]) { --inv; } Integer h = idx.lower(i); if (h != null) { if (arr[h] > arr[i]) { --inv; } sl.remove(new Pair(arr[h] + arr[i], h)); if (arr[h] > s) { ++inv; } sl.add(new Pair(arr[h] + s, h)); } Integer k = idx.higher(j); if (k != null) { if (arr[j] > arr[k]) { --inv; } sl.remove(new Pair(arr[j] + arr[k], j)); if (s > arr[k]) { ++inv; } sl.add(new Pair(s + arr[k], i)); } arr[i] = s; idx.remove(j); } return ans; } } -
class Solution { public: int minimumPairRemoval(vector<int>& nums) { int n = nums.size(); int inv = 0; set<pair<long long, int>> sl; set<int> idx; vector<long long> arr(nums.begin(), nums.end()); for (int i = 0; i < n; ++i) idx.insert(i); for (int i = 0; i < n - 1; ++i) { if (nums[i] > nums[i + 1]) { ++inv; } sl.insert({(long long) nums[i] + nums[i + 1], i}); } int ans = 0; while (inv > 0) { ++ans; auto it = sl.begin(); long long s = it->first; int i = it->second; sl.erase(it); auto j_it = idx.upper_bound(i); int j = *j_it; if (arr[i] > arr[j]) { --inv; } auto i_it = idx.find(i); if (i_it != idx.begin()) { auto h_it = prev(i_it); int h = *h_it; if (arr[h] > arr[i]) { --inv; } sl.erase({arr[h] + arr[i], h}); if (arr[h] > s) { ++inv; } sl.insert({arr[h] + s, h}); } auto k_it = next(j_it); if (k_it != idx.end()) { int k = *k_it; if (arr[j] > arr[k]) { --inv; } sl.erase({arr[j] + arr[k], j}); if (s > arr[k]) { ++inv; } sl.insert({s + arr[k], i}); } arr[i] = s; idx.erase(j); } return ans; } }; -
class Solution: def minimumPairRemoval(self, nums: List[int]) -> int: n = len(nums) sl = SortedList() idx = SortedList(range(n)) inv = 0 for i in range(n - 1): sl.add((nums[i] + nums[i + 1], i)) if nums[i] > nums[i + 1]: inv += 1 ans = 0 while inv: ans += 1 s, i = sl.pop(0) pos = idx.index(i) j = idx[pos + 1] if nums[i] > nums[j]: inv -= 1 if pos > 0: h = idx[pos - 1] if nums[h] > nums[i]: inv -= 1 sl.remove((nums[h] + nums[i], h)) if nums[h] > s: inv += 1 sl.add((nums[h] + s, h)) if pos + 2 < len(idx): k = idx[pos + 2] if nums[j] > nums[k]: inv -= 1 sl.remove((nums[j] + nums[k], j)) if s > nums[k]: inv += 1 sl.add((s + nums[k], i)) nums[i] = s idx.remove(j) return ans -
func minimumPairRemoval(nums []int) (ans int) { type pair struct{ s, i int } n := len(nums) inv := 0 sl := redblacktree.NewWith[pair, struct{}](func(a, b pair) int { return cmp.Or(a.s-b.s, a.i-b.i) }) idx := redblacktree.New[int, struct{}]() for i := 0; i < n; i++ { idx.Put(i, struct{}{}) } for i := 0; i < n-1; i++ { if nums[i] > nums[i+1] { inv++ } sl.Put(pair{nums[i] + nums[i+1], i}, struct{}{}) } for inv > 0 { ans++ it := sl.Iterator() it.First() p := it.Key() sl.Remove(p) s, i := p.s, p.i jNode, _ := idx.Ceiling(i + 1) j := jNode.Key if nums[i] > nums[j] { inv-- } if hNode, ok := idx.Floor(i - 1); ok { h := hNode.Key if nums[h] > nums[i] { inv-- } sl.Remove(pair{nums[h] + nums[i], h}) if nums[h] > s { inv++ } sl.Put(pair{nums[h] + s, h}, struct{}{}) } if kNode, ok := idx.Ceiling(j + 1); ok { k := kNode.Key if nums[j] > nums[k] { inv-- } sl.Remove(pair{nums[j] + nums[k], j}) if s > nums[k] { inv++ } sl.Put(pair{s + nums[k], i}, struct{}{}) } nums[i] = s idx.Remove(j) } return }