Skip to content

2915. Length of the Longest Subsequence That Sums to Target 👍

Approach 1: 2D DP

  • Time: $O(n \cdot \texttt{target})$
  • Space: $O(n \cdot \texttt{target})$
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Solution {
 public:
  int lengthOfLongestSubsequence(vector<int>& nums, int target) {
    const int n = nums.size();
    // dp[i][j] := the maximum length of any subsequence of the first i numbers
    // that sum to j
    vector<vector<int>> dp(n + 1, vector<int>(target + 1, -1));

    for (int i = 0; i <= n; ++i)
      dp[i][0] = 0;

    for (int i = 1; i <= n; ++i) {
      const int num = nums[i - 1];
      for (int j = 1; j <= target; ++j)
        // 1. Skip `num`.
        if (j < num || dp[i - 1][j - num] == -1)
          dp[i][j] = dp[i - 1][j];
        // 2. Skip `num` or pick `num`.
        else
          dp[i][j] = max(dp[i - 1][j], 1 + dp[i - 1][j - num]);
    }

    return dp[n][target];
  }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Solution {
  public int lengthOfLongestSubsequence(List<Integer> nums, int target) {
    final int n = nums.size();
    // dp[i][j] := the maximum length of any subsequence of the first i numbers
    // that sum to j
    int[][] dp = new int[n + 1][target + 1];
    Arrays.stream(dp).forEach(A -> Arrays.fill(A, -1));

    for (int i = 0; i <= n; ++i)
      dp[i][0] = 0;

    for (int i = 1; i <= n; ++i) {
      final int num = nums.get(i - 1);
      for (int j = 1; j <= target; ++j) {
        // 1. Skip `num`.
        if (j < num || dp[i - 1][j - num] == -1)
          dp[i][j] = dp[i - 1][j];
        // 2. Skip `num` or pick `num`.
        else
          dp[i][j] = Math.max(dp[i - 1][j], 1 + dp[i - 1][j - num]);
      }
    }

    return dp[n][target];
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution:
  def lengthOfLongestSubsequence(self, nums: list[int], target: int) -> int:
    n = len(nums)
    # dp[i][j] := the maximum length of any subsequence of the first i numbers
    # that sum to j
    dp = [[-1] * (target + 1) for _ in range(n + 1)]

    for i in range(n + 1):
      dp[i][0] = 0

    for i in range(1, n + 1):
      num = nums[i - 1]
      for j in range(1, target + 1):
        # 1. Skip `num`.
        if j < num or dp[i - 1][j - num] == -1:
          dp[i][j] = dp[i - 1][j]
        # 2. Skip `num` or pick `num`.
        else:
          dp[i][j] = max(dp[i - 1][j], 1 + dp[i - 1][j - num])

    return dp[n][target]

Approach 2: 1D DP

  • Time: $O(n \cdot \texttt{target})$
  • Space: $O(\texttt{target})$
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class Solution {
 public:
  int lengthOfLongestSubsequence(vector<int>& nums, int target) {
    // dp[i] := the maximum length of any subsequence of numbers so far that
    // sum to j
    vector<int> dp(target + 1);

    for (const int num : nums)
      for (int i = target; i >= num; --i)
        if (i == num || dp[i - num] > 0)
          dp[i] = max(dp[i], 1 + dp[i - num]);

    return dp[target] > 0 ? dp[target] : -1;
  }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class Solution {
  public int lengthOfLongestSubsequence(List<Integer> nums, int target) {
    // dp[i] := the maximum length of any subsequence of numbers so far that
    // sum to j
    int[] dp = new int[target + 1];

    for (final int num : nums)
      for (int i = target; i >= num; --i)
        if (i == num || dp[i - num] > 0)
          dp[i] = Math.max(dp[i], 1 + dp[i - num]);

    return dp[target] > 0 ? dp[target] : -1;
  }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class Solution:
  def lengthOfLongestSubsequence(self, nums: list[int], target: int) -> int:
    # dp[i] := the maximum length of any subsequence of numbers so far that
    # sum to j
    dp = [0] * (target + 1)

    for num in nums:
      for i in range(target, num - 1, -1):
        if i == num or dp[i - num] > 0:
          dp[i] = max(dp[i], 1 + dp[i - num])

    return dp[target] if dp[target] > 0 else -1