You are given a 0-indexed array of integers nums
, and an integer target
.
Return the length of the longest subsequence of nums
that sums up to target
. If no such subsequence exists, return -1
.
A subsequence is an array that can be derived from another array by deleting some or no elements without changing the order of the remaining elements.
Example 1:
Input: nums = [1,2,3,4,5], target = 9 Output: 3 Explanation: There are 3 subsequences with a sum equal to 9: [4,5], [1,3,5], and [2,3,4]. The longest subsequences are [1,3,5], and [2,3,4]. Hence, the answer is 3.
Example 2:
Input: nums = [4,1,3,2,1,5], target = 7 Output: 4 Explanation: There are 5 subsequences with a sum equal to 7: [4,3], [4,1,2], [4,2,1], [1,1,5], and [1,3,2,1]. The longest subsequence is [1,3,2,1]. Hence, the answer is 4.
Example 3:
Input: nums = [1,1,5,4,5], target = 3 Output: -1 Explanation: It can be shown that nums has no subsequence that sums up to 3.
Constraints:
1 <= nums.length <= 1000
1 <= nums[i] <= 1000
1 <= target <= 1000
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force method for finding the longest subsequence with a target sum is like trying every possible combination. We'll check absolutely every subsequence to see if it adds up to the target, and if it does, we'll compare its length to the longest one we've found so far.
Here's how the algorithm would work step-by-step:
def longest_subsequence_with_target_sum_brute_force(numbers, target):
longest_subsequence = []
# Iterate through all possible subsequences
for i in range(1 << len(numbers)):
current_subsequence = []
current_sum = 0
for j in range(len(numbers)):
# Check if the j-th element is included in the current subsequence
if (i >> j) & 1:
current_subsequence.append(numbers[j])
current_sum += numbers[j]
# Check if the current subsequence sums to the target
if current_sum == target:
# Check if current subsequence is longer than the longest found so far
if len(current_subsequence) > len(longest_subsequence):
longest_subsequence = current_subsequence
return longest_subsequence
The key is to efficiently reuse calculations to avoid redundant work. We use a technique to store and recall the results of smaller subproblems to build towards the final answer, making the process much faster.
Here's how the algorithm would work step-by-step:
def find_longest_subsequence(numbers, target_sum):
number_count = len(numbers)
# Initialize a table to store minimum lengths for each sum.
minimum_lengths = [[float('inf')] * (target_sum + 1) for _ in range(number_count + 1)]
minimum_lengths[0][0] = 0
for i in range(1, number_count + 1):
for current_sum in range(target_sum + 1):
# Determine whether to include the current number or not.
if numbers[i-1] <= current_sum:
minimum_lengths[i][current_sum] = min(
minimum_lengths[i-1][current_sum],
minimum_lengths[i-1][current_sum - numbers[i-1]] + 1
)
# If current number exceeds sum, exclude it.
else:
minimum_lengths[i][current_sum] = minimum_lengths[i-1][current_sum]
if minimum_lengths[number_count][target_sum] == float('inf'):
return -1
# The result holds the length of longest subsequence for target
return minimum_lengths[number_count][target_sum]
Case | How to Handle |
---|---|
Null or empty input array | Return 0, indicating no subsequence sums to the target. |
Array with only one element, which equals target | Return 1 as the length of the subsequence is 1. |
Array with only one element, which does not equal target | Return 0, indicating no valid subsequence. |
Array contains only positive numbers and target is negative | Return 0, as a subsequence of positive numbers cannot sum to a negative target. |
Array contains zeros and the target is zero | The subsequence consisting of all zeros is a valid solution, return the count of zeros. |
Array contains negative numbers and the target is positive | Standard dynamic programming or recursion with memoization handles this correctly. |
Very large array and target, potential integer overflow in sums | Use a data type that can accommodate larger sums, such as long, or check for potential overflow before calculations. |
No subsequence sums to the target | Return 0, indicating no valid subsequence exists. |