Administrator
Published on 2025-05-15 / 1 Visits
0
0

LeetCode Study Note | Problem 15: 3Sum

โœจ Problem Description

Given an integer array nums, return all the unique triplets [nums[i], nums[j], nums[k]] such that i โ‰  j โ‰  k, and nums[i] + nums[j] + nums[k] == 0.

๐Ÿ” Constraints:

  • Solution set must not contain duplicate triplets.

  • The answer should be a list of triplets, not index-based.

  • Input array can have both positive and negative numbers.


๐Ÿงฉ Core Idea

Although this problem sounds like a straightforward extension of the classic Two Sum, it introduces new challenges:

  • Need to find all combinations, not just one.

  • Must eliminate duplicates.

  • Return triplets of values, not indices.

This changes the optimal strategy from hash-based lookup to a sort + two-pointer approach.


๐Ÿงช Why Not Use HashMap like Two Sum?

In Two Sum:

  • Only one valid pair is needed.

  • Index-based lookup is prioritized.

  • No duplicates or ordering constraints.

In 3Sum:

  • Need all unique value triplets.

  • Sorting makes it easier to skip duplicates.

  • Two-pointer technique becomes efficient after sorting.

So in short:

โœ… Two Sum โ†’ HashMap is optimal

โœ… Three Sum โ†’ Sorting + Two Pointers is optimal


โœ… Java Solution: 3Sum with Sorting + Two Pointers

import java.util.*;

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        Arrays.sort(nums); // Step 1: sort the array

        for (int i = 0; i < nums.length - 2; ++i) {
            if (i > 0 && nums[i] == nums[i - 1]) continue; // Skip duplicate a

            int target = -nums[i];
            int left = i + 1, right = nums.length - 1;

            while (left < right) {
                int sum = nums[left] + nums[right];
                if (sum == target) {
                    res.add(Arrays.asList(nums[i], nums[left], nums[right]));

                    // Skip duplicates
                    while (left < right && nums[left] == nums[left + 1]) left++;
                    while (left < right && nums[right] == nums[right - 1]) right--;

                    left++;
                    right--;
                } else if (sum < target) {
                    left++;
                } else {
                    right--;
                }
            }
        }

        return res;
    }
}


What if Two Sum also needed:

  • All pairs (not just one)?

  • No duplicates?

  • Only value-based results?

Then it would require sorting + two pointers, just like 3Sum.

class Solution {
    public List<List<Integer>> twoSumUniquePairs(int[] nums, int target) {
        List<List<Integer>> res = new ArrayList<>();
        Arrays.sort(nums);

        int left = 0, right = nums.length - 1;

        while (left < right) {
            int sum = nums[left] + nums[right];
            if (sum == target) {
                res.add(Arrays.asList(nums[left], nums[right]));

                while (left < right && nums[left] == nums[left + 1]) left++;
                while (left < right && nums[right] == nums[right - 1]) right--;

                left++;
                right--;
            } else if (sum < target) {
                left++;
            } else {
                right--;
            }
        }

        return res;
    }
}


๐Ÿ“Œ Key Takeaways

Technique

When to Use

Notes

HashMap (O(n))

One pair, return indices (Two Sum classic)

Efficient for single-solution lookup

Sorting + Two Pointers

All unique pairs/triplets, value output

Ideal for de-duplication and scanning

Sorting

Always consider when problem involves uniqueness and combination generation

Enables clean logic and reduces corner cases


Comment