15.三数之和
本题的解法主要使用了双指针法,虽然哈希法也能用,但是会更复杂。
最开始写的一版运行超时了,主要是没有考虑到以下代码中的第1.2.7个注释点(知识点),另外在循环上也有点晕。通过看解析,得到以下解决方法:
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
record = []
nums.sort()
for i in range(len(nums)):
# 1.如果第一个元素已经大于0,不需要进一步检查
if nums[i] > 0:
return record
# 2.从第二个元素开始,比较与前一个的大小,跳过相同的元素以避免重复
if i > 0 and nums[i] == nums[i-1]:
continue
# 3.在循环内定义left and right,使得每次循环两个指针的位置联动变化
left = i + 1
right = len(nums) - 1
# 4.因为题目中要求三个数字不能是同一个元素,即指针不能指向同一个位置,因此是“<”
while left < right:
res = nums[i] + nums[left] + nums[right] # 5.赋予一个值减少计算的次数
# 6.共三个条件,依次判断并执行
if res < 0:
left += 1
elif res > 0:
right -= 1
else:
record.append([nums[i], nums[left], nums[right]])
# 7.每一次记录后,都判断后面有无相同的元素,跳过以避免重复
while left < right and nums[left] == nums[left + 1]:
left += 1
while left < right and nums[right] == nums[right - 1]:
right -= 1
# 8.如果没有重复的元素,两个指针就向中靠拢,并开始下一轮
right -= 1
left += 1
return record
18.四数之和
在三数之和外多加一个循环,同时把去重操作也多做一遍,比较重要的是剪枝操作。ij两个固定值,left, right游走,在上题的基础上,新增的步骤打了“****”的标记。如果这个会了,那么五数之和,n数之和,万变不离其宗!
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
record = []
size = len(nums)
nums.sort()
for j in range(size):
# ****剪枝(可选)
if nums[j] > target and nums[j] > 0 and target > 0:
break
# ****1.从第二个元素开始,比较与前一个的大小,跳过相同的元素以避免重复
if j > 0 and nums[j] == nums[j-1]:
continue
for i in range(j+1, size):
# ****剪枝(可选)
if nums[i] + nums[j]> target and target > 0:
break
# ****2.从第3个元素开始,比较与前一个的大小,跳过相同的元素以避免重复
if i > j+1 and nums[i] == nums[i-1]:
continue
# 3.在循环内定义left and right,使得每次循环两个指针的位置联动变化
left = i + 1
right = size - 1
# 4.因为题目中要求三个数字不能是同一个元素,即指针不能指向同一个位置,因此是“<”
while left < right:
res = nums[j] + nums[i] + nums[left] + nums[right] # ****5.赋予一个值减少计算的次数
# 6.共三个条件,依次判断并执行
if res < target:
left += 1
elif res > target:
right -= 1
else:
record.append([nums[j], nums[i], nums[left], nums[right]])
# 7.每一次记录后,都判断后面有无相同的元素,跳过以避免重复
while left < right and nums[left] == nums[left + 1]:
left += 1
while left < right and nums[right] == nums[right - 1]:
right -= 1
# 8.如果没有重复的元素,两个指针就向中靠拢,并开始下一轮
right -= 1
left += 1
return record

被折叠的 条评论
为什么被折叠?



