Three Integer Sum
Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] where nums[i] + nums[j] + nums[k] == 0, and the indices i, j and k are all distinct.
The output should not contain any duplicate triplets. You may return the output and the triplets in any order.
Example 1:
Input: nums = [-1,0,1,2,-1,-4]
Output: [[-1,-1,2],[-1,0,1]]
Explanation:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0.
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0.
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0.
The distinct triplets are [-1,0,1] and [-1,-1,2].
Example 2:
Input: nums = [0,1,1]
Output: []
Explanation: The only possible triplet does not sum up to 0.
Example 3:
Input: nums = [0,0,0]
Output: [[0,0,0]]
Explanation: The only possible triplet sums up to 0.
Constraints:
3 <= nums.length <= 1000
-10^5 <= nums[i] <= 10^5
Solution
The most easy-to-understand way I think is two-pointers algorithm. First, we sort the list of numbers in ascending order. Then, we traverse the list, taking current number as the first number in tuple, we can do two-pointers on the subarray on its right, where the left pointer begins from the number just after current number and the right pointer begins from the last number. For each number we have traversed, it takes O(n)O(n)O(n) to finish the two pointers and find potential combinations, so the overall time complexity is O(n2)O(n^2)O(n2).
Code
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
ans = []
nums.sort()
for i in range(len(nums)):
if nums[i] > 0:
break
if i > 0 and nums[i] == nums[i-1]:
continue
j = i+1
k = len(nums)-1
while j < k:
if nums[j] + nums[k] > -nums[i]:
k -= 1
elif nums[j] + nums[k] < -nums[i]:
j += 1
else:
ans.append([nums[i], nums[j], nums[k]])
j += 1
while nums[j] == nums[j-1] and j < k:
j += 1
return ans