Length of the Longest Subsequence That Sums to Target
MEDIUMDescription
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 <= 10001 <= nums[i] <= 10001 <= target <= 1000
Approaches
Checkout 4 different approaches to solve Length of the Longest Subsequence That Sums to Target. Click on different approaches to view the approach and algorithm in detail.
Bottom-Up Dynamic Programming
This approach is an iterative version of the memoized recursion, often called bottom-up dynamic programming. It solves the problem by building up a solution from the smallest subproblems. This problem can be framed as a classic 0/1 Knapsack problem, where items are the numbers in nums, their 'weight' is their value, their 'value' is 1 (since we want to maximize the count), and the knapsack capacity is the target.
Algorithm
- Create a 2D DP table,
dp[n + 1][target + 1]. dp[i][j]will store the length of the longest subsequence using elements fromnums[0...i-1]that sums toj.- Initialize the table with a value indicating impossibility, like -1.
- Set the base case:
dp[i][0] = 0for allifrom 0 ton, as a sum of 0 is always possible with an empty subsequence of length 0. - Iterate from
i = 1ton(for each number innums). - Inside, iterate from
j = 1totarget(for each possible sum). - For each
dp[i][j], calculate the value based on two choices fornums[i-1]:- Don't include
nums[i-1]: The length isdp[i-1][j]. - Include
nums[i-1]: Ifj >= nums[i-1]anddp[i-1][j - nums[i-1]]is not -1, the length is1 + dp[i-1][j - nums[i-1]].
- Don't include
- Set
dp[i][j]to the maximum of the valid options. - The final answer is
dp[n][target].
We use a 2D array dp of size (n+1) x (target+1). dp[i][j] represents the maximum length of a subsequence using the first i numbers from nums that sums up to j. We fill this table iteratively. For each number nums[i-1], and for each possible sum j, we decide whether to include nums[i-1] in the subsequence or not. The value of dp[i][j] is determined by taking the maximum of these two choices: (1) the length without including the current number, which is dp[i-1][j], and (2) the length if we include the current number, which is 1 + dp[i-1][j - nums[i-1]]. The second choice is only possible if the target j is at least nums[i-1] and a valid subsequence existed for the subproblem dp[i-1][j - nums[i-1]].
import java.util.Arrays;
import java.util.List;
class Solution {
public int lengthOfLongestSubsequence(List<Integer> nums, int target) {
int n = nums.size();
int[][] dp = new int[n + 1][target + 1];
// Initialize dp table with -1 to indicate that a sum is not possible.
for (int[] row : dp) {
Arrays.fill(row, -1);
}
// Base case: a sum of 0 can always be achieved with an empty subsequence (length 0).
for (int i = 0; i <= n; i++) {
dp[i][0] = 0;
}
for (int i = 1; i <= n; i++) {
int num = nums.get(i - 1);
for (int j = 1; j <= target; j++) {
// Option 1: Exclude the current number. The length is the same as before.
dp[i][j] = dp[i - 1][j];
// Option 2: Include the current number, if possible.
if (j >= num && dp[i - 1][j - num] != -1) {
dp[i][j] = Math.max(dp[i][j], 1 + dp[i - 1][j - num]);
}
}
}
return dp[n][target];
}
}
Complexity Analysis
Pros and Cons
- Avoids recursion and potential stack overflow issues.
- Generally slightly faster in practice than the top-down approach due to no recursion overhead.
- The logic is a clear implementation of the 0/1 Knapsack pattern.
- Uses O(n * target) space, which is not optimal.
Code Solutions
Checking out 3 solutions in different languages for Length of the Longest Subsequence That Sums to Target. Click on different languages to view the code.
Video Solution
Watch the video walkthrough for Length of the Longest Subsequence That Sums to Target
Similar Questions
5 related questions you might find useful
Patterns:
Data Structures:
Companies:
Subscribe to Scale Engineer newsletter
Learn about System Design, Software Engineering, and interview experiences every week.
No spam, unsubscribe at any time.