Three Sum Problem All Unique Triplets in DSA Go - Time & Space Complexity
We want to understand how the time needed to find all unique triplets that sum to zero grows as the input list gets bigger.
How does the number of steps change when the list size increases?
Analyze the time complexity of the following code snippet.
func threeSum(nums []int) [][]int {
sort.Ints(nums)
var res [][]int
for i := 0; i < len(nums)-2; i++ {
if i > 0 && nums[i] == nums[i-1] {
continue
}
left, right := i+1, len(nums)-1
for left < right {
sum := nums[i] + nums[left] + nums[right]
if sum == 0 {
res = append(res, []int{nums[i], nums[left], nums[right]})
left++
right--
for left < right && nums[left] == nums[left-1] {
left++
}
for left < right && nums[right] == nums[right+1] {
right--
}
} else if sum < 0 {
left++
} else {
right--
}
}
}
return res
}
This code finds all unique triplets in the array that add up to zero by sorting and using two pointers.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The outer loop runs through each element, and for each, the inner two-pointer loop scans the remaining elements.
- How many times: Outer loop runs about n times; inner loop moves pointers across the array, roughly n times in total per outer iteration.
As the input size grows, the number of operations grows roughly with the square of the input size.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 100 |
| 100 | About 10,000 |
| 1000 | About 1,000,000 |
Pattern observation: Doubling the input size roughly quadruples the work, showing a square growth pattern.
Time Complexity: O(n²)
This means the time needed grows roughly with the square of the input size, so if the list doubles, the work increases about four times.
[X] Wrong: "Because there are three numbers, the time complexity must be O(n³)."
[OK] Correct: The sorting and two-pointer method reduce the inner search to linear time, so the total work is n times n, not n times n times n.
Understanding this time complexity helps you explain how to efficiently find triplets and shows you can optimize nested loops with sorting and pointers.
"What if we used three nested loops without sorting or two pointers? How would the time complexity change?"
Practice
Three Sum Problem All Unique Triplets in data structures and algorithms?Solution
Step 1: Understand the problem statement
The problem asks to find all unique groups of three numbers in an array whose sum is zero.Step 2: Identify the goal
The goal is to find triplets (three numbers) that add up to zero without duplicates.Final Answer:
Find all unique triplets in an array that sum to zero -> Option BQuick Check:
Three Sum Problem = Find unique triplets summing to zero [OK]
- Confusing with pair sum problems
- Ignoring uniqueness of triplets
- Trying to find max or min instead of sum
Solution
Step 1: Recall Go slice initialization syntax
In Go, slices are initialized with square brackets and type, e.g., []int{...}.Step 2: Check each option
nums := []int{1, -1, 0, 2, -2} uses correct syntax: nums := []int{1, -1, 0, 2, -2}. Others use invalid syntax.Final Answer:
nums := []int{1, -1, 0, 2, -2} -> Option AQuick Check:
Go slice syntax = []int{...} [OK]
- Using parentheses or braces instead of curly braces
- Missing type declaration []int
- Using array literal syntax without type
func threeSum(nums []int) [][]int {
sort.Ints(nums)
var res [][]int
for i := 0; i < len(nums)-2; i++ {
if i > 0 && nums[i] == nums[i-1] {
continue
}
left, right := i+1, len(nums)-1
for left < right {
sum := nums[i] + nums[left] + nums[right]
if sum == 0 {
res = append(res, []int{nums[i], nums[left], nums[right]})
for left < right && nums[left] == nums[left+1] {
left++
}
for left < right && nums[right] == nums[right-1] {
right--
}
left++
right--
} else if sum < 0 {
left++
} else {
right--
}
}
}
return res
}
fmt.Println(threeSum([]int{-1, 0, 1, 2, -1, -4}))Solution
Step 1: Sort and iterate through the array
The sorted array is [-4, -1, -1, 0, 1, 2]. The code skips duplicates and uses two pointers to find triplets summing to zero.Step 2: Identify unique triplets summing to zero
Triplets found are [-1, -1, 2] and [-1, 0, 1]. These are appended to the result.Final Answer:
[[-1, -1, 2], [-1, 0, 1]] -> Option CQuick Check:
Unique triplets summing zero = [[-1,-1,2],[-1,0,1]] [OK]
- Not sorting array before processing
- Not skipping duplicates causing repeated triplets
- Incorrect pointer movement logic
func threeSum(nums []int) [][]int {
sort.Ints(nums)
var res [][]int
for i := 0; i < len(nums)-2; i++ {
left, right := i+1, len(nums)-1
for left < right {
sum := nums[i] + nums[left] + nums[right]
if sum == 0 {
res = append(res, []int{nums[i], nums[left], nums[right]})
left++
right--
} else if sum < 0 {
left++
} else {
right--
}
}
}
return res
}Solution
Step 1: Analyze duplicate handling
The code does not skip duplicate values for i, left, or right, which can cause duplicate triplets in the result.Step 2: Confirm other parts are correct
Initialization of pointers and sorting are correct. The return statement is after loops, so no premature return.Final Answer:
Missing check to skip duplicate elements for i, left, and right -> Option DQuick Check:
Skipping duplicates is essential to avoid repeated triplets [OK]
- Not skipping duplicates causing repeated triplets
- Incorrect pointer updates after finding a triplet
- Sorting with wrong function
nums := []int{-2, 0, 1, 2, -1, -1, 3}, which of the following is the correct set of all unique triplets that sum to zero?Solution
Step 1: Sort the array and find triplets
Sorted array: [-2, -1, -1, 0, 1, 2, 3]. Find unique triplets summing to zero by two-pointer method.Step 2: Identify all unique triplets
Triplets are [-2, -1, 3], [-2, 0, 2], [-1, -1, 2], and [-1, 0, 1]. These cover all unique zero sums.Final Answer:
[[-2, -1, 3], [-2, 0, 2], [-1, -1, 2], [-1, 0, 1]] -> Option AQuick Check:
All unique triplets summing zero = [[-2, -1, 3], [-2, 0, 2], [-1, -1, 2], [-1, 0, 1]] [OK]
- Missing some triplets due to not skipping duplicates
- Including triplets with repeated elements incorrectly
- Not sorting array before processing
Ready to prove it?
Pass the test and this pattern moves unknown
