Count the picks that hit an exact total

Backtracking Mid-level Python 3.13+ Kotlin 2.4+ Reviewed By Best Latest Apps

Predict the output

What does this print?

Python 3.13
from itertools import combinations
prices, goal = [2, 3, 5, 7], 7
hits = [c for r in range(len(prices) + 1)
        for c in combinations(prices, r) if sum(c) == goal]
print(len(hits), hits)

Options

Choose an answer, then open Show answer below to check it.

Show answer

Answer: A 2 [(7,), (2, 5)]

Right: 7 alone, and 2 with 5.

The brute-force check tries all 16 selections; the backtracking version reaches the same two without exploring branches that already overshoot.

Why not the others?
  • B 3 [(7,), (2, 5), (2, 3)]. 2 and 3 add up to 5.
  • C 1 [(2, 5)]. A single item can be a selection too.
The decision tree for counting selections that hit a total: each node takes or skips one price, branches that pass the goal are pruned and hits are marked found, for two inputs.

Steps come from running the Python solution.

Text version

Prices 2, 3, 5 with goal 5:

  • start: call
    • take 2: call
      • take 3: found
      • skip 3: call
        • take 5: pruned
        • skip 5: call
    • skip 2: call
      • take 3: call
        • take 5: pruned
        • skip 5: call
      • skip 3: call
        • take 5: found
        • skip 5: call

Result: 2 · 13 calls (call 9, found 2, pruned 2)

Prices 1, 2, 3, 4 with goal 4:

  • start: call
    • take 1: call
      • take 2: call
        • take 3: pruned
        • skip 3: call
          • take 4: pruned
          • skip 4: call
      • skip 2: call
        • take 3: found
        • skip 3: call
          • take 4: pruned
          • skip 4: call
    • skip 1: call
      • take 2: call
        • take 3: pruned
        • skip 3: call
          • take 4: pruned
          • skip 4: call
      • skip 2: call
        • take 3: call
          • take 4: pruned
          • skip 4: call
        • skip 3: call
          • take 4: found
          • skip 4: call

Result: 2 · 25 calls (call 17, found 2, pruned 6)

30-second answer

Walk the items in order and, for each, branch into 'take it' and 'skip it'. Stop a branch as soon as the running total equals the goal (count it) or passes it (prune it). Without pruning this is O(2ⁿ) time with O(n) recursion depth; pruning cuts that sharply on real inputs. For large goals with small prices, a DP table over totals is faster.

Practise saying it · 45 s. No recording, just a timer

Explain include-or-skip backtracking with pruning.

Say your answer out loud, then check which of these points you covered:

  • Take or skip each item
  • Stop at the goal, prune past it
  • 2ⁿ worst case

Deep dive

This is the include-or-skip template behind most selection questions.

Pruning on 'total > goal' is valid only because prices are positive.

Sorting prices ascending lets you break out of a loop early, a stronger prune.

Python solution Ran on Python 3.13.5 · mypy --strict
Python 3.13
def count_picks(prices: list[int], goal: int) -> int:
    def walk(i: int, total: int) -> int:
        if total == goal:
            return 1  # adding more positive prices only overshoots
        if total > goal or i == len(prices):
            return 0  # pruned or out of items
        take = walk(i + 1, total + prices[i])
        return take + walk(i + 1, total)
    return walk(0, 0)

Kotlin Ran on Kotlin 2.4.21 · JDK 21.0.12.1
Kotlin 2.4
fun countPicks(prices: List<Int>, goal: Int): Int {
    fun walk(i: Int, total: Int): Int {
        if (total == goal) return 1 // more items only overshoot
        if (total > goal || i == prices.size) return 0
        return walk(i + 1, total + prices[i]) + walk(i + 1, total)
    }
    return walk(0, 0)
}

Common mistakes

  • Counting the same selection twice by continuing after the goal is hit with skips.
  • Pruning with negative prices, which can bring the total back down.

Senior take & follow-ups

Draw the first three levels of the decision tree; it explains both the cost and the prune.

Follow-up questions

Think of your answer first, then open the hint.

  1. When is DP better?

    Show hint

    When the goal is small enough for a table: O(n · goal) instead of exponential.

  2. How do you list the selections instead of counting?

    Show hint

    Keep a path list, record a copy at each hit, and undo after each take.

What each operation costs: Depth First Search

From the author

DSA Master - Data & Algorithms

Free on iPhone and iPad: watch 50+ data structures and algorithms step through animations, run the code in the playground, and try the daily challenge.

Suggest a fix if something here is wrong or out of date.