skip to content

How does subset-sum decide whether valued items split into two equal-value halves?

level: middleimportance: must knowfreq 66%

answer

  1. an equal split fixes each half's target
  2. one half forces the other
  3. check the total's parity first
  4. each amount is both cost and worth
  5. cells answer reachable or not

basics

~20 s

Add everything up; an odd total cannot halve, so answer no immediately. Otherwise ask subset-sum whether some subset reaches exactly half the total, using a boolean table where a cell means the sum is reachable rather than storing a maximum.

solid answer

~50 s

Take an estate of indivisible appraised items to be divided between two heirs. Sum every appraisal; if that total is odd, no equal split exists and you stop. Otherwise the target is `total / 2`, and the question becomes subset-sum: is there a subset whose appraisals sum to exactly the target? One half determines the other, so you only search for one. Structurally it is the same knapsack skeleton with each item's amount serving as both its cost and its worth, and with the `max` replaced by a logical OR — `reach[s]` means "sum `s` is achievable from the items processed so far", initialised with `reach[0] = true` because the empty selection reaches zero. Cost is O(n * total/2) cell updates, and the table's width is driven by the money magnitudes, not by the item count.

go deeper

for a junior

Recall that subset-sum asks a yes-or-no question — does some subset total exactly the target — rather than asking for a maximum, and that half the total is the target for an equal split.

for a middle

Explain the reduction end to end: parity check, target of half the total, each amount acting as both cost and worth, cells holding reachability, and the empty-selection seed at index zero.

for a senior

Be ready to report the actual split rather than its existence, and to answer the practical version — the smallest achievable difference — when no exact halving exists.

for a principal

Judge whether an exact reachability table is affordable at the real appraisal magnitudes, and whether an approximate or negotiated split is the cheaper answer for the business.

## The problem An estate holds `n` indivisible items, each with an integer appraised amount. Two heirs must receive equal total value, and no item can be cut in half. Deciding whether such a split exists is the equal-partition question, and it is subset-sum wearing a different hat. ## The reduction, in two moves **Move one: fix the target.** If the two halves must be equal, each is worth exactly `total / 2`. So an odd total is an immediate no — two integers that sum to an odd number cannot be equal. This parity check costs one pass and saves the entire table when it fires; interviewers notice when it is missing. **Move two: search one side only.** You never need to construct both halves. Any subset summing to `total / 2` forces its complement to sum to the same amount, so the whole question reduces to: *is `total / 2` reachable as a subset sum?* ## From value maximisation to reachability The knapsack skeleton is choose-or-skip under a budget. Here each item's amount is simultaneously what it costs (it consumes budget) and what it is worth (it contributes to the sum). When cost and worth are the same number, maximising value under a budget of `target` degenerates: the best you could ever do is exactly fill the budget. So instead of storing "best value so far", the cell stores a single bit: `reach[s]` = true if some subset of the items processed so far sums to exactly `s`. The base case is `reach[0] = true`: the empty selection reaches zero. Getting this wrong is fatal in a quiet way — start with every cell false and no cell ever becomes true, because each update reads an earlier cell. Everything else starts false. Processing an item of amount `a` marks newly reachable sums: `s` becomes reachable if `s - a` was already reachable without this item. The answer is `reach[target]` after all items. Note the boolean form still owes the same debt as the value form: each item may be used only once, so the update must read the state from *before* the item was offered. ## Cost, and what the cost is measured in There are `n` items and `target + 1` cells, so O(n · total/2) updates and O(total) memory in the flattened form. The second factor is a **money magnitude**, not a count of inputs — ten items appraised in whole currency units are cheap; ten items appraised to the cent in the millions are not. A boolean table is the cheapest possible cell, and packing bits makes the memory small even for large targets, but the time is still proportional to the target. ## Variants that ride on the same table - **Report the split, not just its existence.** Keep the two-dimensional table (or a parent-pointer trail) and walk back from `(n, target)`: if the cell was already true without item `i`, skip it; otherwise assign item `i` to the first heir and move to `target - amount[i]`. - **As even as possible.** If no exact halving exists — which is the common real-world case — find the largest reachable `s <= total / 2`. The best achievable difference is `total - 2s`, and that single scan of the finished row answers the practical question the heirs actually have. - **Count the splits.** Replace the boolean with an integer count and the OR with addition, and the table reports how many subsets hit the target. Each unordered split is then counted twice, once from each side. ## Assumptions worth stating out loud The table is indexed by sums, so amounts must be **non-negative integers**. Negative amounts (a debt attached to an item) break the monotone budget framing and need the whole range shifted by an offset before indexing. Amounts of zero are harmless but make the split non-unique. Items must be indivisible — that is what forces the yes/no decision per item rather than a proportional one. ## The wrong answers to avoid - "You have to try all 2^n subsets." Only if you refuse to reuse sub-answers; two different subsets reaching the same running sum are interchangeable from that point on, which is exactly what the table exploits. - "Both halves need the same number of items." Equal value, not equal count — three small items can balance one large one. - "The cell holds how many items were used." It holds one bit of reachability; conflating the two produces a table that answers a question nobody asked.

  • Why must the reachability array start with index zero set to true?
    Because the empty selection sums to zero, and every later cell is derived from an earlier reachable one. If the whole array starts false, each update reads false and writes false, so no sum is ever marked and the algorithm reports that even a trivially splittable estate cannot be divided. That single cell is the seed the entire table grows from.
  • No exact halving exists. How do you report the fairest possible split instead?
    Run the same table to `total / 2` and then scan the finished row downward for the largest reachable sum `s`. One heir takes that subset, the other takes the complement, and the gap between them is `total - 2s` — the provably smallest achievable difference. It costs one extra linear scan, and it answers the question the heirs actually care about.
  • What breaks if an item carries a negative amount, such as an attached debt?
    The table is indexed by sums, and negative amounts make sums move in both directions, so a plain zero-based index no longer covers the reachable range. You shift the whole range by an offset large enough to cover the most negative achievable total and index relative to that. The recurrence is unchanged; only the addressing is.

saying these in an interview costs you the question

  • Says you must enumerate all subsets to decide it
  • Runs the whole table even when the total is odd
  • Starts the reachability array entirely false, index zero included
  • Insists both halves need the same number of items
  • Treats a cell as a count of items rather than reachability

context