The Problem

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

Notice that the solution set must not contain duplicate triplets.

Interactive Visualization

Speed:
Sorted Array
Found Triplets
No triplets found yet.
Code
fun threeSum(nums: IntArray): List<List<Int>> {    nums.sort()    val result = mutableListOf<List<Int>>()    for (i in 0 until nums.size - 2) {        if (i > 0 && nums[i] == nums[i - 1])            continue  // skip duplicate        var left = i + 1; var right = nums.size - 1        while (left < right) {            val total = nums[i] + nums[left] + nums[right]            if (total == 0) {                result.add(listOf(nums[i], nums[left], nums[right]))                while (left < right && nums[left] == nums[left + 1])                    left++  // skip dup                while (left < right && nums[right] == nums[right - 1])                    right--  // skip dup                left++                right--            } else if (total < 0) {                left++            } else {                right--            }        }    }    return result}
Status & Log
Press Step or Play to begin.

How It Works

Key Insight

After sorting the array, fix one element nums[i] and use a two-pointer technique on the remaining subarray to find pairs that sum to -nums[i]. Sorting enables both the two-pointer approach and efficient duplicate skipping.

The Algorithm

  • Sort the array first. This makes it possible to use two pointers and skip duplicates.
  • Fix element i: iterate i from 0 to n - 3. Skip if nums[i] == nums[i-1] (duplicate fixed element).
  • Two pointers: set left = i + 1, right = n - 1. Compute total = nums[i] + nums[left] + nums[right].
  • If total == 0: record the triplet, skip duplicate lefts and rights, then move both pointers inward.
  • If total < 0: we need a larger sum, so move left right.
  • If total > 0: we need a smaller sum, so move right left.

Complexity

Time O(nยฒ)
Space O(1) ignoring output

Sorting takes O(n log n). The outer loop runs n times and the inner two-pointer scan is O(n), giving O(nยฒ) total. No extra space is used beyond the output list.