The O(n) Club: 4Sum II — When Hashmaps Save You from Loop Purgatory

The O(n) Club: 4Sum II — When Hashmaps Save You from Loop Purgatory

⚡ TL;DR

Given four integer arrays, count (i, j, k, l) such that nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0. Brute-force = four loops and eternal suffering. Hashmap = two loops and enough free time to make a fresh coffee.

// Don't. Just... don't.
int count = 0;
for (int a : nums1)
  for (int b : nums2)
    for (int c : nums3)
      for (int d : nums4)
        if (a + b + c + d == 0)
          count++;
// Runtime: Somewhere between "never" and "heat death of universe"

🧠 How Devs Usually Mess This Up

Ah, the four-array panic: your first instinct is to nest four for-loops, right? Congratulations, you’ve just invented the world’s slowest lottery machine! Others think this is “4Sum Classic” and scramble to deduplicate quadruplets or sort arrays—totally unnecessary. 4Sum II just wants the raw count, not a curated playlist of unique sums.

🔍 What’s Actually Going On

This problem is secretly about teamwork: split the arrays in half, pairwise add the first two, and stash all their sums in a HashMap (with count of occurrences). Now, for every sum from the other two arrays, just look up its negative in your map—because (a + b + c + d) == 0 exactly when a + b == -(c + d). It’s like coding with a calculator, but faster and with 99% less cursing.

🛠️ PseudoCode

  • Hash all possible a + b sums:
    Map<Integer, Integer> abMap = new HashMap<>();
    for (int a : nums1)
      for (int b : nums2)
        abMap.put(a + b, abMap.getOrDefault(a + b, 0) + 1);

    Now abMap holds “sum” → frequency, like a bouncer tracking repeat guests.

  • For each c + d, check: how many (a, b) pairings cancel them out?
    int count = 0;
    for (int c : nums3)
      for (int d : nums4)
        count += abMap.getOrDefault(-(c + d), 0);

    If the complement exists, add up its frequency. If not, add zero. It’s basically algorithmic matchmaking.

  • Return the count. No sorting, no deduplication, just joy.
    return count;

💻 The Code

public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
    Map<Integer, Integer> abMap = new HashMap<>();
    for (int a : nums1)
        for (int b : nums2)
            abMap.put(a + b, abMap.getOrDefault(a + b, 0) + 1);
    int count = 0;
    for (int c : nums3)
        for (int d : nums4)
            count += abMap.getOrDefault(-(c + d), 0);
    return count;
}

⚠️ Pitfalls, Traps & Runtime Smacks

  • Looking up (c + d) instead of its negative: You’ll wonder why you always get zero, and probably lose sleep.
  • Trying to deduplicate quadruplets: Yawn. Just count the matches, and live your best life.
  • HashMap memory binge: HashMap will take up to O(n²) space, so if your arrays are as long as the daily Jira backlog, watch the RAM.
  • Time & Space, No Gym Required: O(n²) in both; manageable for typical input sizes, infinitely better than O(n⁴) loops-of-doom.

🧠 Interviewer Brain-Tattoo

Brute-forcers blame slow CPUs. Hashmappers blame nothing — their code runs before the pizza arrives.

Previous Article

The O(n) Club: Remove All Adjacent Duplicates in String — Now With 100% Less Regret Than Brute Force

Next Article

The O(n) Club: Average of Levels in a Binary Tree (Or Why Java Hates Decimals)