You are given an integer array nums
and an integer goal
.
You want to choose a subsequence of nums
such that the sum of its elements is the closest possible to goal
. That is, if the sum of the subsequence's elements is sum
, then you want to minimize the absolute difference abs(sum - goal)
.
Return the minimum possible value of abs(sum - goal)
.
Note that a subsequence of an array is an array formed by removing some elements (possibly all or none) of the original array.
Example 1:
Input: nums = [5,-7,3,5], goal = 6 Output: 0 Explanation: Choose the whole array as a subsequence, with a sum of 6. This is equal to the goal, so the absolute difference is 0.
Example 2:
Input: nums = [7,-9,15,-2], goal = -5 Output: 1 Explanation: Choose the subsequence [7,-9,-2], with a sum of -4. The absolute difference is abs(-4 - (-5)) = abs(1) = 1, which is the minimum.
Example 3:
Input: nums = [1,2,3], goal = -7 Output: 7
Constraints:
1 <= nums.length <= 40
-107 <= nums[i] <= 107
-109 <= goal <= 109
This problem asks to find the minimum absolute difference between the sum of a subsequence of the input array nums
and a given goal
. The constraints suggest that a brute-force approach (iterating through all possible subsequences) would be too slow. The efficient solutions leverage a divide-and-conquer strategy combined with binary search.
Core Idea:
nums
into two halves.l
) from the left half's set, find the closest sum (r
) in the sorted right half's set such that l + r
is closest to the goal
. Binary search is used to efficiently find this closest sum.Time Complexity Analysis:
nums
. This is because each element can either be included or excluded in a subsequence, resulting in 2n/2 possibilities for each half.Overall Time Complexity: The overall time complexity is dominated by the DFS and combining steps, which are both approximately O(n * 2n/2). This is significantly better than the brute-force O(n * 2n) approach.
Space Complexity Analysis:
The space complexity is dominated by the sets (or lists) used to store the subsequence sums. Each set can contain approximately 2n/2 elements. Therefore, the space complexity is O(2n/2).
Code Explanation (Python):
The Python code efficiently implements this strategy:
class Solution:
def minAbsDifference(self, nums: List[int], goal: int) -> int:
n = len(nums)
left = set()
right = set()
self.getSubSeqSum(0, 0, nums[: n // 2], left)
self.getSubSeqSum(0, 0, nums[n // 2 :], right)
result = inf
right = sorted(right)
rl = len(right)
for l in left:
remaining = goal - l
idx = bisect_left(right, remaining)
if idx < rl:
result = min(result, abs(remaining - right[idx]))
if idx > 0:
result = min(result, abs(remaining - right[idx - 1]))
return result
def getSubSeqSum(self, i: int, curr: int, arr: List[int], result: Set[int]):
if i == len(arr):
result.add(curr)
return
self.getSubSeqSum(i + 1, curr, arr, result)
self.getSubSeqSum(i + 1, curr + arr[i], arr, result)
The getSubSeqSum
function recursively generates all subsequence sums for a given array portion. The main function then combines the results from both halves using binary search to find the closest sum to the goal. bisect_left
from the bisect
module efficiently finds the insertion point for a value in a sorted list.
The other languages (Java, C++, Go) implement the same algorithm with minor syntactic differences. They use similar data structures and techniques to achieve the same time and space complexity.