两数之和
三数之和
参考:https://leetcode-cn.com/problems/3sum/solution/3sumpai-xu-shuang-zhi-zhen-yi-dong-by-jyd/
- 暴力法解决的时间复杂度为 O ( n 3 ) O(n^3) O(n3),具体算法略。
- 除了以上的方法,我并没有想出其他解法。于是看了其他人的笔记——使用 “双指针” ,这里进行记录。
假设nums
数组如下:
Step1、将给定的nums
数组进行排序(升序)
Step2、固定三个指针中的一个指针k
到索引最小处,然后另外两个指针l
,r
分别固定在除了k
指向的位置之外的最左侧与最右侧。
Step3、双指针l
,r
交替向中间移动,记录对于每个固定指针k
的所有满足nums[k] + nums[l] + nums[r] == 0
的l
,r
组合。然而,并不是简单地直接进行算法的书写就可以了,因为我们要分析出详尽的步骤以及特殊情况:
程序如下(Python实现):
def threeSum(nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
nums.sort() # 原地升序排序
result, k = [], 0 # k,l,r三个“指针”用索引来表示
for k in range(len(nums) - 2):
if nums[k] > 0:
break
if k > 0 and nums[k] == nums[k-1]:
continue
l, r = k+1, len(nums) - 1
while l < r:
s = nums[k] + nums[l] + nums[r]
if s < 0:
l += 1
while l < r and nums[l] == nums[l-1]:
l += 1
elif s > 0:
r -= 1
while l < r and nums[r] == nums[r+1]:
r -= 1
else:
result.append([nums[k], nums[l], nums[r]])
# 因为已经得到了使和为0的三个值了,所以如果再只改变l或r都不可能再得到和为0的结果;
# 而正确的做法就是使r,l同时改变,同时仍进行while判断
l += 1
r -= 1
while l < r and nums[l] == nums[l-1]:
l += 1
while l < r and nums[r] == nums[r+1]:
r -= 1
return result
print(threeSum([-1, 0, 1, 2, -1, -4]))