15. 3Sum
method: 2 pointers
1 prepare a set
2 sort the array
3 for each i loop, use 2 pointers to reduce time in sorted array
4 use set to avoid repeating
Python:
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
output = set()
nums.sort()
for i in range(len(nums)):
low, high = i + 1, len(nums) - 1
while low < high:
num_sum = nums[i] + nums[low] + nums[high]
if num_sum == 0:
output.add((nums[i], nums[low], nums[high]))
low += 1
high -= 1
elif num_sum > 0:
high -= 1
else:
low += 1
return output
method 2: 通过
if i > 0 and nums[i] == nums[i-1]:
continue
避免太多重复元素的运算
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
res = set()
nums.sort()
for i in range(len(nums)):
if i > 0 and nums[i] == nums[i-1]:
continue # if already use i, no need to use any more
low, high = i + 1, len(nums) - 1
while low < high:
three = nums[i] + nums[low] + nums[high]
if three == 0:
res.add((nums[i], nums[low], nums[high]))
low += 1
high -= 1
elif three < 0:
low += 1
else:
high -= 1
return res
JS: optimized 2 pointers
var threeSum = function(nums) {
nums.sort((a, b) => a - b)
const res = [];
for(let i = 0; i < nums.length; i++) {
if(nums[i] === nums[i - 1]) {
continue // skip same elements to avoid duplicate triplets
}
let start = i+1, end = nums.length - 1
while(start < end) {
const sum = nums[i] + nums[start] + nums[end]
if(sum === 0) {
res.push([nums[i], nums[start], nums[end]]);
start++
end--
while (start < end && nums[start] === nums[start - 1]) {
start += 1; // skip same elements to avoid duplicate triplets
}
while (start < end && nums[end] === nums[end + 1]) {
end -= 1; // skip same elements to avoid duplicate triplets
}
} else if (sum < 0) {
start++;
} else {
end--;
}
}
}
return res;
};
16. 3Sum Closest
method: 2 pointers => leetcode 15 -> 16
1 prepare a res = infinity
2 sort the array
3 for each i in loop, use 2 pointers to find the closest
4 if equals to target, return target
5 else return closest
6 if low >= high, output res
class Solution:
def threeSumClosest(self, nums: List[int], target: int) -> int:
res = float('inf')
nums.sort()
for i in range(len(nums)):
lo, hi = i + 1, len(nums) - 1
while lo < hi:
three = nums[i] + nums[lo] + nums[hi]
if three == target:
return target
if abs(three - target) < abs(res - target):
res = three
if three < target:
lo += 1
else:
hi -= 1
return res
method: 补充一句话加快速度
if i > 0 and nums[i] == nums[i-1]:
continue
因为已经遍历过的元素没有必要再次遍历,再次遍历是的结果一定是他的子集
class Solution:
def threeSumClosest(self, nums: List[int], target: int) -> int:
res = float('inf')
nums.sort()
for i in range(len(nums)):
if i > 0 and nums[i] == nums[i-1]:
continue
lo, hi = i + 1, len(nums) - 1
while lo < hi:
three = nums[i] + nums[lo] + nums[hi]
if three == target:
return target
if abs(three - target) < abs(res - target):
res = three
if three < target:
lo += 1
else:
hi -= 1
return res
18. 4Sum
method: leetcode 15, 16 : 2 pointers
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
num_set = set()
nums.sort()
for i in range(len(nums) - 1):
for j in range(i + 1, len(nums)):
lo, hi = j + 1, len(nums) - 1
while lo < hi:
four = nums[i] + nums[j] + nums[lo] + nums[hi]
if four == target:
num_set.add((nums[i], nums[j], nums[lo], nums[hi]))
lo += 1
hi -= 1
elif four < target:
lo += 1
else:
hi -= 1
return num_set
加上一句:if i > 0 and nums[i] == nums[i-1]: continue, 加快速度。
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
num_set = set()
nums.sort()
for i in range(len(nums) - 1):
if i > 0 and nums[i] == nums[i-1]: continue
for j in range(i + 1, len(nums)):
lo, hi = j + 1, len(nums) - 1
while lo < hi:
four = nums[i] + nums[j] + nums[lo] + nums[hi]
if four == target:
num_set.add((nums[i], nums[j], nums[lo], nums[hi]))
lo += 1
hi -= 1
elif four < target:
lo += 1
else:
hi -= 1
return num_set