LeetCode18 4Sum
Author: Stefan Su
Create time: 2022-10-31 19:53:46
Location: New York City, NY, USA
Description Medium
Given an array nums
of n
integers, return an array of all the unique quadruplets [nums[a], nums[b], nums[c], nums[d]]
such that:
0 <= a, b, c, d < n
a
,b
,c
, andd
are distinct.nums[a] + nums[b] + nums[c] + nums[d] == target
You may return the answer in any order.
Example 1
Input: nums = [1,0,-1,0,-2,2], target = 0
Output: [[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
Example 2
Input: nums = [2,2,2,2,2], target = 8
Output: [[2,2,2,2]]
Constrains
1 <= nums.length <= 200
-10
9<= nums[i] <= 10
9-10
9<= target <= 10
9
Analysis
Almost same as LeetCode15 3 sum, but one more layer of for-loop with more details to be considered.
Solution
- Two pointers version
class Solution(object):
def fourSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[List[int]]
"""
# Two pointer version
# sort the nums first
nums = sorted(nums)
# initialize an list to store result
result = []
# start from the first element
for k in range(len(nums)):
# KEY OPERATION: break condition
# in the case below, the for loop will be broken
# For example, [..., ..., ..., ..., 4, 5, ...], nums[k] = 4 and target is 2
# Then, any number after nums[k] can never be sumed up less than target (2)
if nums[k] > target and nums[k] > 0 and target > 0:
break
# KEY OPERATION: remove duplication
# if next element is same as current one, then jump over to next k
# each for loop, check this again
if k > 0 and nums[k] == nums[k - 1]:
continue
# after k is not duplicated, loop and check the second number i
for i in range(k + 1, len(nums)):
# KEY OPERATION: break condition
# in the case below, similar to the first k break condition operation
# consider nums[i] + nums[k] as an entity
# then, compare the value of this entity with target while target > 0
# and nums[i] + nums[k] > 0
if nums[i] + nums[k] > target and nums[i] + nums[k] > 0 and target > 0:
break
# KEY OPERATION: remove duplication
# similar in out layer's loop for checking k
if i > k + 1 and nums[i] == nums[i - 1]:
continue
# consider last two numbers
# initialize left and right pointer
left = i + 1
right = len(nums) - 1
while right > left:
# if nums[k] + nums[i] + nums[left] + nums[right] > 0, then move right index to a previous index
if nums[k] + nums[i] + nums[left] + nums[right] > target:
right -= 1
# if nums[k] + nums[i] + nums[left] + nums[right] < 0, then move left index to a latter index
elif nums[k] + nums[i] + nums[left] + nums[right] < target:
left += 1
else:
# append current valid list into result
result.append([nums[k], nums[i], nums[left], nums[right]])
# KEY OPERATION: remove duplication operation for right
# if nums[right] == nums[right - 1], then move right to a previous index
# For example, nums = [-1, -1, -1, 0, 0, 0, 1, 1, 1]
# current is nums[0] + nums[3] + nums[4] + nums[8] = 0
# but if we replace nums[8] with nums[7] or nums[6], it works as well
# therefore, we should move right index to remove this duplicated output
# although, the index of value 1 can be different (6, 7, 8)
while right > left and nums[left] == nums[left + 1]:
left += 1
# KEY OPERATION: remove duplication operation for left
# if nums[left] == nums[left + 1], then move left to a latter index
# same explanation as movement of right index
while right > left and nums[right] == nums[right - 1]:
right -= 1
# update left and right to more central position
left += 1
right -= 1
return result
Hopefully, this blog can inspire you when solving LeetCode18. For any questions, please comment below.