LC015 - 3Sum

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.

Example

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]. Notice that the order of the output and the order of the triplets does not matter.

Solution

Naive

Complexity is O(n2logn)O(n^2 \log n) time and O(n)O(n) space.

def threeSum(self, nums: List[int]) -> List[List[int]]:
	target = 0
	nums.sort()
	s = set()
	output = []
	
	for i in range(len(nums)):
		j = i + 1
		k = len(nums) - 1
		
		while j < k:
			sum = nums[i] + nums[j] + nums[k]

			if sum == target:
				s.add((nums[i], nums[j], nums[k]))
				j += 1
				k -= 1
			
			elif sum < target:
				j += 1
			
			else:
				k -= 1
			
	output = list(s)
	return output

Improved

In theory, this solution would be slower than a two pointer solution, which is in theoryO(nlogn)O(n \log n). However, in this approach, checking the negative and positive complement while in the worst case is O(n2)O(n^2), runs faster the majority of times assuming that the ratio of positive and negative values is not skewed because this solution has better constant time factor. Sorting here is effectively O(1)O(1) since we sort three elements at a time.

Last updated