Subsequence with Sum K

medium

You're given an array of positive integers arr and a target k. Return true if some subsequence of arr has elements that sum to exactly k, and false otherwise.

A subsequence is what's left after you delete zero or more elements from the array — for each element you either keep it or drop it, and the kept elements stay in their original order. Every element can be used at most once.

Since a sum doesn't care about order, the real question is: can you choose some subset of the elements whose total is exactly k?

Hints

For every element you face the same tiny decision. What is it — and how many ways can the whole array be decided?
Take it or leave it: recursing on both choices at every index enumerates every subsequence. Track only how much of k is still needed.
Many branches arrive at the same (index, remaining) state — cache those answers, or flip the question and build a boolean table of which totals from 0 to k are reachable.

Common doubts

No. A subarray is contiguous; a subsequence just keeps relative order and may skip elements. And since a sum ignores order entirely, this problem is really about choosing a subset of elements.
No — each element is a one-shot take-or-skip decision. Allowing reuse turns this into a different (unbounded) problem, and it is exactly why the optimal DP sweeps its sums downward.
It sums to 0, and since k >= 1 it can never be the answer here. But sum 0 being reachable is the seed of every solution — it is why reachable[0] starts as true.
Take arr = [6, 5, 3] with k = 8: greedily grabbing the largest note 6 leaves 2, which nothing fits — yet 5 + 3 = 8. Local best picks can lock you out of the exact total; you need to explore or tabulate.

Interview follow-ups

Both prunes break: an overshoot can recover, so remaining < 0 is no longer terminal, and reachable sums are no longer bounded by k. You would key the DP by a hash map of reachable sums, or use meet-in-the-middle for small n.
Identical states, different value: store counts instead of booleans — dp[s] += dp[s - num] with the same downward sweep. Existence is just the count-question asked as a yes/no.
Yes — either record the take/skip choice per memo state and replay it, or walk the DP table backwards from k, greedily undoing any num with reachable[k - num] set in the previous row.
The O(n * k) table becomes infeasible — the DP is pseudo-polynomial. For small n (around 40) you would split the array in half, enumerate each half's 2^(n/2) sums, and match them with a sorted lookup: meet in the middle.

Fun facts

  • This is the decision version of Subset Sum — one of the 21 problems Richard Karp proved NP-complete in 1972. The DP still solves it fast because it is pseudo-polynomial: quick when k is small, hopeless when k has many digits.
  • The reachable-totals row compresses into a bitset: adding a number becomes bits |= bits << num, lighting 64 totals per CPU instruction.
  • The same take-or-skip skeleton powers Partition Equal Subset Sum, Target Sum, and the whole 0/1 knapsack family — learn it once, reuse it for years.

Asked at

AmazonMicrosoftGoogleFlipkartAdobe
Frequently Sometimes Occasionally
Example 1
Input: arr = [10, 1, 2, 7, 6, 1, 5], k = 8
Output: true
Several picks work: [1, 7] sums to 8, and so does [2, 6].
Example 2
Input: arr = [2, 3, 5, 7, 9], k = 100
Output: false
Even taking every element only reaches 2 + 3 + 5 + 7 + 9 = 26.
Constraints

- 1 <= arr.length <= 2000 - 1 <= arr[i] <= 1000 - 1 <= k <= 2000

Solve this problem →