Problem Description
Given an integer array nums of length 3 * n, you are allowed to remove exactly n elements (as a subsequence) from nums. The remaining 2 * n elements are then divided into two consecutive parts of size n each. Let sum_first be the sum of the first n elements and sum_second be the sum of the last n elements. Your task is to remove n elements such that the difference (sum_first - sum_second) is minimized.
Key Insights
- We are effectively choosing which elements to remove to balance the sums of the two contiguous parts.
- The problem can be reframed as: maximize the sum of the first part (by selecting n large elements from the first 2n) and minimize the sum of the second part (by selecting n small elements from the last 2n).
- Two heaps (a min-heap and a max-heap) are used to greedily maintain the best candidate sums while sliding over valid subarrays.
- Precompute the maximum sum possible for the left part and the minimum sum possible for the right part for every potential partition point in the middle.
Space and Time Complexity
Time Complexity: O(n log n) – Each of the two passes over n elements involves heap operations, each costing O(log n). Space Complexity: O(n) – For storing the heaps and precomputed prefix/suffix arrays.
Solution
We solve the problem in two phases:
- For the left segment (first 2n elements), maintain a min-heap while iterating from left to right. Start by adding the first n elements and computing their sum. Then continue through indices n to 2n-1, adding each element to the heap and removing the smallest element (if necessary) in order to always retain the n largest elements from the left portion. Store the sum at each step as a candidate for sum_first.
- For the right segment (last 2n elements), maintain a max-heap while iterating backwards from right to left. Start by adding the last n elements and computing their sum. Then continue backwards through indices 2n-1 downto n, adding each element and removing the largest element (ensuring we keep the n smallest elements from this portion). Store the sum at each step as a candidate for sum_second.
- Finally, iterate over all valid split points (from n to 2*n) and compute the difference: leftSum[i] - rightSum[i]. The minimum of these differences is the answer.
Important details:
- The heaps allow us to efficiently update the running sums as we consider including a new candidate element and possibly excluding a less optimal element.
- The pre-computation of candidate sums for every partition point is key to achieving an O(n log n) solution without exploring all removal subsequences.