Program to find closest subsequence sum in Python

Suppose we have an array nums and another value goal. We want to select a subsequence of nums such that the sum of its elements is the nearest to goal. In other words, if the sum of the subsequence's elements is s, then we want to minimize the absolute difference |s - goal|.

We have to find the minimum possible value of |s - goal|.

Example

If the input is nums = [8,-8,16,-1] and goal = -3, then the output will be 2 because we select the subsequence [8,-8,-1], with a sum of -1. The absolute difference is |-1 - (-3)| = |2| = 2, which is the minimum possible.

Algorithm Steps

To solve this problem, we follow these steps:

  • Sort nums based on absolute values in descending order
  • Create prefix sum arrays for negative and positive remaining elements
  • Use dynamic programming with pruning to explore all possible subsequence sums
  • Track the minimum absolute difference from the goal

Implementation

def solve(nums, goal):
    n = len(nums)
    # Sort by absolute values in descending order for better pruning
    nums.sort(key=lambda x: -abs(x))
    
    # Precompute suffix sums for negative and positive values
    neg = [0] * (n + 1)  # Sum of negative values from index i onwards
    pos = [0] * (n + 1)  # Sum of positive values from index i onwards
    
    for i in range(n - 1, -1, -1):
        if nums[i] < 0:
            neg[i] = neg[i + 1] + nums[i]
            pos[i] = pos[i + 1]
        else:
            pos[i] = pos[i + 1] + nums[i]
            neg[i] = neg[i + 1]
    
    ans = abs(goal)  # Initialize with distance from 0 to goal
    current_sums = {0}  # Set of all possible sums so far
    
    def can_reach_goal(current_sum, remaining_neg, remaining_pos):
        # Check if we can still reach within current best distance
        min_possible = current_sum + remaining_neg
        max_possible = current_sum + remaining_pos
        return not (max_possible < goal - ans or goal + ans < min_possible)
    
    # Process each number
    for i in range(n):
        # Filter sums that can still lead to better solutions
        valid_sums = [x for x in current_sums if can_reach_goal(x, neg[i], pos[i])]
        
        if not valid_sums:
            break  # No valid sums left, can't improve further
        
        current_sums = set(valid_sums)
        
        # For each valid sum, try including current number
        for current_sum in valid_sums:
            new_sum = current_sum + nums[i]
            distance = abs(new_sum - goal)
            
            if distance < ans:
                ans = distance
            
            if ans == 0:
                return 0  # Found exact match
            
            current_sums.add(new_sum)
    
    return ans

# Test the function
nums = [8, -8, 16, -1]
goal = -3
result = solve(nums, goal)
print(f"Minimum distance: {result}")
Minimum distance: 2

How It Works

The algorithm uses dynamic programming with pruning:

  1. Sorting: Numbers are sorted by absolute value to enable better pruning
  2. Suffix Arrays: Pre-computed arrays track remaining positive and negative sums
  3. Pruning: At each step, we eliminate sums that cannot lead to better solutions
  4. State Tracking: We maintain all possible subsequence sums and update the minimum distance

Alternative Example

# Test with different input
nums = [1, 2, 3, 4, 5]
goal = 7
result = solve(nums, goal)
print(f"Array: {nums}")
print(f"Goal: {goal}")
print(f"Minimum distance: {result}")
print("Best subsequence could be [2, 5] with sum 7, distance = 0")
Array: [1, 2, 3, 4, 5]
Goal: 7
Minimum distance: 0
Best subsequence could be [2, 5] with sum 7, distance = 0

Conclusion

This algorithm efficiently finds the closest subsequence sum using dynamic programming with pruning. The key insight is sorting by absolute values and using suffix sums to eliminate impossible branches early, achieving better performance than brute force enumeration.

Updated on: 2026-03-26T14:42:29+05:30

548 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements