Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Coding Interview Patterns  Module 16 – Backtracking

Meet in the middle algorithm for n up to 40

Pick gifts whose total is closest to a voucher from up to 40 items: the problem, a measured brute force over all subsets, and the signal for meet in the middle.

  • Advanced
  • 35 minutes
  • Examples run with Python 3.14.8, Pyodide 314.0.7, Node.js 24.21.0, quickjs 0.32.0, Java 25, Clang 21.0.0 and Go 1.27.1
  • By MySmartCoPilot
Free intro, Pro: 8 of 35 minutes free
Free: The problem: gifts closest to a voucher · The brute force, and why it fails at these sizes · What to notice. With a pass: the other 13 sections and 3 interview answers, about 27 minutes.

What you will learn

  • Split a search over 2ⁿ subsets into two searches over 2^(n/2) half subsets, and combine them
  • Find the subset total closest to a target for up to 40 values
  • Combine the halves with sorting and binary search, or with one sweep of two pointers
  • Prove that the best pair of half totals is the best subset, checking partners on both sides
  • Measure the enumeration of 2²⁰ totals in Python and C++, and size the memory it needs

Before you start

What you’ll learn · Before you start

What you will learn

  • Split a search over 2ⁿ subsets into two searches over 2^(n/2) half subsets, and combine them
  • Find the subset total closest to a target for up to 40 values
  • Combine the halves with sorting and binary search, or with one sweep of two pointers
  • Prove that the best pair of half totals is the best subset, checking partners on both sides
  • Measure the enumeration of 2²⁰ totals in Python and C++, and size the memory it needs

Before you start

On this page

The meet in the middle algorithm solves a search over every subset of n items by splitting the items into two halves, searching each half on its own, and combining the two lists of results. For n = 40 that replaces 2⁴⁰, about 10¹², subsets with two lists of 2²⁰, about a million totals each, which a laptop handles in seconds. The classic case is choosing items whose total comes as close as possible to a target.

The problem: gifts closest to a voucher

The problem

A gift shop lists n items with whole-number prices, and you hold a voucher worth V. Choose any set of items, each at most once, whose total is as close to V as possible, above or below. Write closest_subset_sum(values, target), which returns the smallest possible abs(total − target); the empty set counts, with a total of 0. Limits: 1 ≤ n ≤ 40, prices up to 10⁹, and 0 ≤ V ≤ 4 × 10¹⁰.

  1. Prices 9, 14, 21, 35 and 52, voucher 60: the answer is 1. No set totals 60, and 9 + 52 = 61.
  2. Prices 400, 250, 175, 990, 610, 330 and 85, voucher 1000: 10, from 990 alone or from 400 + 610.
  3. Prices 12, 7 and 30, voucher 5: 2, from the 7 alone, which beats the empty set’s 5.
The totals of the sets of 9 and 14, and of the sets of 21, 35 and 52; a line joins 9 and 52, whose sum 61 is closest to 60.Two halves of 9, 14, 21, 35, 52; voucher 60sets of 9, 14sets of 21, 35, 5202135525673871080914234 totals on the left and 8 on the right make all 32sets; the best, 9 + 52 = 61, is one away from 60.

The first example split into two halves

Text description of the diagram

The five prices 9, 14, 21, 35 and 52 are split into a first half, 9 and 14, and a second half, 21, 35 and 52.

  • The left column lists the totals of every set of the first half: 0 (no item), 9, 14 and 23.
  • The right column lists the totals of every set of the second half in increasing order: 0, 21, 35, 52, 56, 73, 87 and 108.

Every set of the five prices is one set from each half, so its total is one left total plus one right total: 4 times 8 makes all 32 sets. A line joins the left total 9 and the right total 52, highlighted: together 61, the total closest to the voucher of 60, one away. No set totals exactly 60.

The brute force, and why it fails at these sizes

Compute the total of every subset, each from the subset that lacks its lowest item, and keep the closest:

The total of every subset, timed Python · brute/brute_force.py
# The brute force: the total of every subset, each built from the subset one smaller, and the closest one kept.
import time


def closest_brute(prices, voucher):
    totals = [0] * (1 << len(prices))  # totals[mask]: the total of the items whose bits are set in mask
    best = abs(voucher)
    for mask in range(1, len(totals)):
        low = mask & -mask  # the lowest item of the subset
        totals[mask] = totals[mask ^ low] + prices[low.bit_length() - 1]
        best = min(best, abs(totals[mask] - voucher))
    return best


print(closest_brute([9, 14, 21, 35, 52], 60))
print(closest_brute([400, 250, 175, 990, 610, 330, 85], 1000))
print(closest_brute([12, 7, 30], 5))

print(" n        subsets   time")
prices = [100_000_000 + (i * 7_919_003) % 900_000_000 for i in range(40)]
for n in range(14, 21, 2):
    start = time.perf_counter()
    closest_brute(prices[:n], sum(prices[:n]) // 3)
    seconds = time.perf_counter() - start
    print(f"{n:2}  {2 ** n:13,}  {seconds:5.2f} s")
print(f"40 items: 2 ** 40 = {2 ** 40:,} subsets, about {seconds * 2 ** 20 / 86400:.0f} days at that speed")

Output

1
10
2
 n        subsets   time
14         16,384   0.00 s
16         65,536   0.01 s
18        262,144   0.05 s
20      1,048,576   0.71 s
40 items: 2 ** 40 = 1,099,511,627,776 subsets, about 9 days at that speed

This output changes from run to run: the times depend on the computer and on what else it is doing

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 brute_force.py

The three answers are right. Each extra item doubles the work, so 20 items, a million subsets, already take a noticeable fraction of a second in Python, and 40 items mean 1,099,511,627,776 subsets, days even at that speed. A compiled language at roughly 10⁸ simple steps a second still needs hours. Pruning cannot rescue it either: with a target to approach from both sides, no partial total is hopeless.

What to notice

  • Every subset is two subsets. Its items in the first half form one subset and its items in the second half another, so its total is a total of the first half plus a total of the second.
  • Half of 40 is small. Each half of 20 items has only 2²⁰ = 1,048,576 subsets.
  • For one left total the best partner is fixed: the right total nearest to V minus that left total.

Four techniques follow:

  • Splitting into halves lists every subset total of each half, about 2 × 2^(n/2) totals instead of 2ⁿ.
  • Sorting one half lets a binary search find, for each left total, the nearest right total.
  • Two pointers sweep both sorted halves once, from opposite ends, and pass every pair that could be closest.
  • Merging by doubling builds a half’s totals already sorted, so no separate sort is needed.

Splitting the items into two halves, step by step Pro: opens with a Pro, Premium or Ultimate pass

In this part:

  • Why the best pair of half totals is the best subset
  • Enumerating 2²⁰ totals, timed in Python and C++
  • Sorted totals without sorting: the doubling merge
  • The code in five languages
  • How much work it does
  • Edge cases and common bugs
  • Variants: counting within a budget, exact totals and a knapsack
  • Follow-up questions
  • Exercise: the closest total for up to 40 values
    • The subset total closest to a target, for up to 40 values
  • A practice set with sample answers
  • Check yourself
  • Interview questions
    • What does meet in the middle gain over trying every subset of n items, and what does it cost?
    • Given 40 integers of up to 10⁹ and a target, return the subset total closest to the target. Walk through your plan with its time and memory in numbers, and name the bugs your tests will look for.
    • Four lists hold 2,000 integers each. Count the ways to pick one number from each list so that the four add up to zero. Trying every choice is 1.6 × 10¹³ combinations. How do you count them, and what does it cost?
    • A planner chooses among 36 parcels, each with a weight of up to 10⁹ grams and a value, for one truck that can carry 10¹⁰ grams, and wants the most value. A table over weights is impossible. Design the search, and say how you keep its lists small.
  • Key takeaways

7 runnable examples (C++, Go, Java, JavaScript, Python) · 1 exercise with sample tests · 3 interview answers · about 22 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

References

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.