Back to blog

2026-06-23

Two Pointer - 3 Sum

Given an array of ints, find all the unique triplets in the array whose sum equals 0.

  1. Each of the indices must be different i!=j, i!=k & j!=k.
  2. The sum of the 3 must equal 0.
  3. The result set of triplets must not contain duplicates, even if they appear multiple times.

Solution

 In order to complete this problem in O(n^2) we need to use the two pointer solution.
Start off by sorting the array to be able deploy the two pointer solution. From here you can start to iterate (n) over the number array and while doing so set 2 pointers, one at (n+1) and the other at the end of the array. Given these 3 numbers you can then sum the values to check if the equal 0. If the first element is greater than 0, stop iterating, given we've sorted the array there will be no possible combo of triplets beyond that point that will equal 0.

 Next, because each iteration will loop through the entirety of the provided array of ints, you can skip (n) if the value of the previous index equals the same as the current index. Example [-1,-1,0,1], the second -1 will be a duplicate of the first -1 combos.

 Now we get into the main portion of the code where we while loop until the left pointer & right pointer meet. It's here we do the calculation of the sum of the 3 values. If the sum is < 0 then the left pointer needs to more 1 more to the right to find the next largest number to solve the equation. If the sum is > 0, then the right pointer needs to move left to find the next lowest number to solve the equation. If the sum equals 0 then both pointers will move the 1 index closer each to avoid duplicates.

  The last bit is if the new values of the left pointer and right pointer are the same as the ones that we just iterated from then continue iterating them both until you find a value that's not the same, so that you avoid duplicates!

**
 * Finds all unique triplets in the array that sum to zero
 * @param nums - Input array of numbers
 * @returns Array of triplets that sum to zero
 */
function threeSum(nums: number[]): number[][] {
    // Sort the array in ascending order for two-pointer approach
    nums.sort((a, b) => a - b);

    const result: number[][] = [];
    const length = nums.length;

    // Iterate through the array, fixing the first element
    // Stop at length-2 since we need at least 3 elements
    // Also stop if current element > 0 (sum can't be zero with all positive numbers)
    for (let firstIndex = 0; firstIndex < length - 2 && nums[firstIndex] <= 0; firstIndex++) {
        // Skip duplicate values for the first element to avoid duplicate triplets
        if (firstIndex > 0 && nums[firstIndex] === nums[firstIndex - 1]) {
            continue;
        }

        // Use two pointers for the remaining elements
        let leftPointer = firstIndex + 1;
        let rightPointer = length - 1;

        // Find pairs that sum with nums[firstIndex] to equal zero
        while (leftPointer < rightPointer) {
            const currentSum = nums[firstIndex] + nums[leftPointer] + nums[rightPointer];

            if (currentSum < 0) {
                // Sum is too small, move left pointer right to increase sum
                leftPointer++;
            } else if (currentSum > 0) {
                // Sum is too large, move right pointer left to decrease sum
                rightPointer--;
            } else {
                // Found a valid triplet
                result.push([nums[firstIndex], nums[leftPointer], nums[rightPointer]]);

                // Move both pointers and skip duplicates
                leftPointer++;
                rightPointer--;

                // Skip duplicate values for the second element
                while (leftPointer < rightPointer && nums[leftPointer] === nums[leftPointer - 1]) {
                    leftPointer++;
                }

                // Skip duplicate values for the third element
                while (leftPointer < rightPointer && nums[rightPointer] === nums[rightPointer + 1]) {
                    rightPointer--;
                }
            }
        }
    }

    return result;
}