CMD Guide
HomeDSAAdvanced Patterns

Introduction to Meet in the Middle

Meet in the middle exploits the fact that 2^n is infeasible but 2^(n/2) is cheap: split the input into two halves, enumerate every combination of each half separately, then pair a result from the left half with a result from the right half using a sort + binary search (or two-pointer) instead of a second nested enumeration — turning an O(2^n) search into roughly O(2^(n/2) · n).

Recognize the pattern

Brute force → optimal

Brute force: enumerate all 2^n subsets of the full array, compute each sum, keep the best ≤ S. Cost: O(2^n) time, O(1) extra space (streaming). For n = 40 that's ~10^12 operations — infeasible in a few seconds.

Optimal (meet in the middle): split the n items into two halves of size n/2. Enumerate all 2^(n/2) subset sums of each half independently (this alone is exponentially cheaper — square-rooting the search space). Sort one half's sums, then for every sum in the other half binary-search for the best complementary value that keeps the total ≤ S.

Complexity, derived

Let h = n/2.

Worked example

Array [3, 15, 14, 9, 6, 2], S = 10 (using the small S from the source so the trace is short). Split: left = [3, 15, 14], right = [9, 6, 2].

HalfSubset sums (all 2^3 = 8 subsets)
left0, 3, 14, 15, 17, 18, 29, 32
right0, 2, 6, 8, 9, 11, 15, 17

Sort right → [0, 2, 6, 8, 9, 11, 15, 17]. Now scan left sums that are ≤ S = 10 (only 0 and 3 qualify) and for each, binary-search the largest right value ≤ (S − left):

sLeftremaining = 10 − sLeftbest sRight ≤ remainingtotal
01099
3769

Best answer: 9 (e.g. subset {9} or {3, 6}), both ≤ S = 10 and no combination beats 9.

Java implementation

static List<Long> generateSubsetSums(int[] arr) {
    int m = arr.length;
    List<Long> sums = new ArrayList<>();
    for (int mask = 0; mask < (1 << m); mask++) {
        long s = 0;
        for (int i = 0; i < m; i++) if ((mask & (1 << i)) != 0) s += arr[i];
        sums.add(s);
    }
    return sums;
}

static long maxSubsetSumAtMostS(int[] nums, long S) {
    int n = nums.length, mid = n / 2;
    int[] left = Arrays.copyOfRange(nums, 0, mid);
    int[] right = Arrays.copyOfRange(nums, mid, n);
    List<Long> sumLeft = generateSubsetSums(left);
    List<Long> sumRight = generateSubsetSums(right);
    Collections.sort(sumRight);
    long best = 0;
    for (long sLeft : sumLeft) {
        if (sLeft > S) continue;
        long remaining = S - sLeft;
        // largest value in sumRight that is <= remaining
        int lo = 0, hi = sumRight.size() - 1, idx = -1;
        while (lo <= hi) {
            int m = (lo + hi) / 2;
            if (sumRight.get(m) <= remaining) { idx = m; lo = m + 1; }
            else hi = m - 1;
        }
        if (idx >= 0) best = Math.max(best, sLeft + sumRight.get(idx));
    }
    return best;
}

Pitfalls

When to use / when not — trade-offs

Use meet in the middle when n is roughly 30–45 (2^n infeasible, 2^(n/2) is not) and the problem decomposes into two independent halves whose results combine via a cheap operation (sum, XOR, pair-count). Compare with:

Takeaways

Recall question

Why is the overall time complexity O(2^(n/2) · n) rather than O(2^(n/2)) alone, and where does the extra factor of n come from?


Pattern derived from the classic subset-sum-under-a-bound formulation; complexity analysis and Java implementation original to this page.

🤖 Don't fully get this? Learn it with Claude

Stuck on Introduction to Meet in the Middle? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **Introduction to Meet in the Middle** (DSA) and want to truly understand it. Explain Introduction to Meet in the Middle from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **Introduction to Meet in the Middle** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **Introduction to Meet in the Middle** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **Introduction to Meet in the Middle** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes