Welcome to Subscribe On Youtube

Formatted question description: https://leetcode.ca/all/2163.html

2163. Minimum Difference in Sums After Removal of Elements (Hard)

You are given a 0-indexed integer array nums consisting of 3 * n elements.

You are allowed to remove any subsequence of elements of size exactly n from nums. The remaining 2 * n elements will be divided into two equal parts:

  • The first n elements belonging to the first part and their sum is sumfirst.
  • The next n elements belonging to the second part and their sum is sumsecond.

The difference in sums of the two parts is denoted as sumfirst - sumsecond.

  • For example, if sumfirst = 3 and sumsecond = 2, their difference is 1.
  • Similarly, if sumfirst = 2 and sumsecond = 3, their difference is -1.

Return the minimum difference possible between the sums of the two parts after the removal of n elements.

 

Example 1:

Input: nums = [3,1,2]
Output: -1
Explanation: Here, nums has 3 elements, so n = 1. 
Thus we have to remove 1 element from nums and divide the array into two equal parts.
- If we remove nums[0] = 3, the array will be [1,2]. The difference in sums of the two parts will be 1 - 2 = -1.
- If we remove nums[1] = 1, the array will be [3,2]. The difference in sums of the two parts will be 3 - 2 = 1.
- If we remove nums[2] = 2, the array will be [3,1]. The difference in sums of the two parts will be 3 - 1 = 2.
The minimum difference between sums of the two parts is min(-1,1,2) = -1. 

Example 2:

Input: nums = [7,9,5,8,1,3]
Output: 1
Explanation: Here n = 2. So we must remove 2 elements and divide the remaining array into two parts containing two elements each.
If we remove nums[2] = 5 and nums[3] = 8, the resultant array will be [7,9,1,3]. The difference in sums will be (7+9) - (1+3) = 12.
To obtain the minimum difference, we should remove nums[1] = 9 and nums[4] = 1. The resultant array becomes [7,5,8,3]. The difference in sums of the two parts is (7+5) - (8+3) = 1.
It can be shown that it is not possible to obtain a difference smaller than 1.

 

Constraints:

  • nums.length == 3 * n
  • 1 <= n <= 105
  • 1 <= nums[i] <= 105

Similar Questions:

Solution 1. Heap

Since we are looking for the minimum difference, we want to minimize the sum of the first part and maximize the sum of the right part.

For the first part, we can use a Max Heap of size N to store the smallest N digits in it.

We traverse from left to right. For each A[i], we push it into the heap. If the heap size is greater than N, we pop the heap top. In this way, we track the smallest N digits and their sum.

Similarly for the right part, but we want the greatest N digits.

  • // OJ: https://leetcode.com/problems/minimum-difference-in-sums-after-removal-of-elements/
    // Time: O(NlogN)
    // Space: O(N)
    class Solution {
    public:
        long long minimumDifference(vector<int>& A) {
            priority_queue<int> L; // storing the smallest N digits in the first part
            priority_queue<int,vector<int>, greater<>> R; // storing the greatest N digits in the right part
            long N = A.size() / 3, ans = LLONG_MAX;
            vector<long> right(A.size());
            for (long i = A.size() - 1, sum = 0; i >= N; --i) { // calculate the greatest N digits in the right part
                R.push(A[i]);
                sum += A[i];
                if (R.size() > N) {
                    sum -= R.top();
                    R.pop();
                }
                if (R.size() == N) right[i] = sum; // `right[i]` is the maximum sum of `N` digits in `A[i:]`
            }
            for (long i = 0, left = 0; i < A.size() - N; ++i) {
                L.push(A[i]);
                left += A[i];
                if (L.size() > N) {
                    left -= L.top();
                    L.pop();
                }
                if (L.size() == N) ans = min(ans, left - right[i + 1]);
            }
            return ans;
        }
    };
    
  • # 2163. Minimum Difference in Sums After Removal of Elements
    # https://leetcode.com/problems/minimum-difference-in-sums-after-removal-of-elements/
    
    from sortedcontainers import SortedList
    
    class Solution:
        def minimumDifference(self, nums: List[int]) -> int:
            m = len(nums)
            n = m // 3
            
            left = SortedList(nums[:n])
            right = SortedList(nums[n:])
            sumLeft = sum(left)
            sumRight = sum(right[-n:])
            res = sumLeft - sumRight
            
            for i in range(n, 2 * n):
                index = right.bisect_left(nums[i])
                
                if index >= len(right) - n:
                    sumRight -= nums[i]
                    sumRight += right[-n-1]
                
                index = left.bisect_left(nums[i])
                
                if index < n:
                    sumLeft += nums[i]
                    sumLeft -= left[n - 1]
                
                right.discard(nums[i])
                left.add(nums[i])
                
                res = min(res, sumLeft - sumRight)
            
            return res
            
    
    
  • class Solution {
        public long minimumDifference(int[] nums) {
            int m = nums.length;
            int n = m / 3;
            long s = 0;
            long[] pre = new long[m + 1];
            PriorityQueue<Integer> pq = new PriorityQueue<>((a, b) -> b - a);
            for (int i = 1; i <= n * 2; ++i) {
                int x = nums[i - 1];
                s += x;
                pq.offer(x);
                if (pq.size() > n) {
                    s -= pq.poll();
                }
                pre[i] = s;
            }
            s = 0;
            long[] suf = new long[m + 1];
            pq = new PriorityQueue<>();
            for (int i = m; i > n; --i) {
                int x = nums[i - 1];
                s += x;
                pq.offer(x);
                if (pq.size() > n) {
                    s -= pq.poll();
                }
                suf[i] = s;
            }
            long ans = 1L << 60;
            for (int i = n; i <= n * 2; ++i) {
                ans = Math.min(ans, pre[i] - suf[i + 1]);
            }
            return ans;
        }
    }
    
  • func minimumDifference(nums []int) int64 {
    	m := len(nums)
    	n := m / 3
    	s := 0
    	pre := make([]int, m+1)
    	q1 := hp{}
    	for i := 1; i <= n*2; i++ {
    		x := nums[i-1]
    		s += x
    		heap.Push(&q1, -x)
    		if q1.Len() > n {
    			s -= -heap.Pop(&q1).(int)
    		}
    		pre[i] = s
    	}
    	s = 0
    	suf := make([]int, m+1)
    	q2 := hp{}
    	for i := m; i > n; i-- {
    		x := nums[i-1]
    		s += x
    		heap.Push(&q2, x)
    		if q2.Len() > n {
    			s -= heap.Pop(&q2).(int)
    		}
    		suf[i] = s
    	}
    	ans := int64(1e18)
    	for i := n; i <= n*2; i++ {
    		ans = min(ans, int64(pre[i]-suf[i+1]))
    	}
    	return ans
    }
    
    func min(a, b int64) int64 {
    	if a < b {
    		return a
    	}
    	return b
    }
    
    type hp struct{ sort.IntSlice }
    
    func (h hp) Less(i, j int) bool  { return h.IntSlice[i] < h.IntSlice[j] }
    func (h *hp) Push(v interface{}) { h.IntSlice = append(h.IntSlice, v.(int)) }
    func (h *hp) Pop() interface{} {
    	a := h.IntSlice
    	v := a[len(a)-1]
    	h.IntSlice = a[:len(a)-1]
    	return v
    }
    
  • function minimumDifference(nums: number[]): number {
        const m = nums.length;
        const n = Math.floor(m / 3);
        let s = 0;
        const pre: number[] = Array(m + 1);
        const q1 = new MaxPriorityQueue();
        for (let i = 1; i <= n * 2; ++i) {
            const x = nums[i - 1];
            s += x;
            q1.enqueue(x, x);
            if (q1.size() > n) {
                s -= q1.dequeue().element;
            }
            pre[i] = s;
        }
        s = 0;
        const suf: number[] = Array(m + 1);
        const q2 = new MinPriorityQueue();
        for (let i = m; i > n; --i) {
            const x = nums[i - 1];
            s += x;
            q2.enqueue(x, x);
            if (q2.size() > n) {
                s -= q2.dequeue().element;
            }
            suf[i] = s;
        }
        let ans = Number.MAX_SAFE_INTEGER;
        for (let i = n; i <= n * 2; ++i) {
            ans = Math.min(ans, pre[i] - suf[i + 1]);
        }
        return ans;
    }
    
    

Discuss

https://leetcode.com/problems/minimum-difference-in-sums-after-removal-of-elements/discuss/1746989/

All Problems

All Solutions