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:
n
elements belonging to the first part and their sum is sumfirst
.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
.
sumfirst = 3
and sumsecond = 2
, their difference is 1
.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
This problem asks to find the minimum difference between the sums of two equal parts of an array after removing n
elements. The solution uses a combination of heaps (priority queues) and prefix/suffix sums to efficiently achieve this.
Core Idea:
Removal of n elements: We need to strategically remove n
elements to minimize the difference between the sums of the remaining two parts (each of size n
).
Prefix and Suffix Sums: Instead of brute-forcing all possible combinations of removed elements, we use prefix sums to efficiently calculate the sum of the smallest n
elements from the beginning of the array and suffix sums for the largest n
elements from the end.
Heaps: To maintain the smallest n
elements in the prefix and largest n
elements in the suffix dynamically as we iterate, we use max-heap (q1
) and min-heap (q2
), respectively. This allows for efficient addition and removal of elements while tracking the sums.
Iteration and Minimization: We iterate through possible split points (where the array is divided into two parts of size n
). For each split point i
, we subtract the suffix sum (suf[i+1]
) from the prefix sum (pre[i]
) to get the difference. We track the minimum difference encountered.
Algorithm:
Initialization:
n
(number of elements to remove).pre
and suf
arrays to store prefix and suffix sums.q1
and min-heap q2
.Prefix Sum Calculation:
2n
elements.s
.q1
.q1
has more than n
elements, remove the largest element (max-heap's top element) and update s
.s
in pre[i]
.Suffix Sum Calculation:
n+1
elements.s
.q2
.q2
has more than n
elements, remove the smallest element (min-heap's top element) and update s
.s
in suf[i]
.Minimization:
n
to 2n
(possible split points).pre[i] - suf[i + 1]
and update the minimum difference ans
if necessary.Time Complexity: O(N log N), dominated by heap operations.
Space Complexity: O(N) to store heaps and prefix/suffix sum arrays.
Code (Python):
import heapq
class Solution:
def minimumDifference(self, nums: List[int]) -> int:
m = len(nums)
n = m // 3
s = 0
pre = [0] * (m + 1)
q1 = [] # Max heap
for i, x in enumerate(nums[: 2 * n], 1):
s += x
heapq.heappush(q1, -x) # Negate for max heap
if len(q1) > n:
s -= -heapq.heappop(q1)
pre[i] = s
s = 0
suf = [0] * (m + 1)
q2 = [] # Min heap
for i in range(m, n, -1):
x = nums[i - 1]
s += x
heapq.heappush(q2, x)
if len(q2) > n:
s -= heapq.heappop(q2)
suf[i] = s
ans = float('inf')
for i in range(n, 2 * n + 1):
ans = min(ans, pre[i] - suf[i + 1])
return ans
Similar implementations can be done in other languages like Java, C++, JavaScript, etc., using their respective priority queue implementations. The core logic remains the same.