学习双指针的运用
方法一:暴力解法(三个循环)
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
nums.sort()
result = []
for i in range(len(nums)):
for j in range(i+1, len(nums)):
for k in range(j+1, len(nums)):
if nums[i] + nums[j] + nums[k] == 0 and [nums[i], nums[j], nums[k]] not in result:
result.append([nums[i], nums[j], nums[k]])
return result
超出时间限制
方法二:排序 + 双指针
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
# 先排序,为了判断是否重复
nums.sort()
result = []
for i in range(len(nums)):
# 对于每一重循环而言,相邻两次枚举的元素不能相同,否则也会造成重复
if i == 0 or nums[i] != nums[i-1]:
# 第三重循环对应的指针
k = len(nums) - 1
for j in range(i+1, len(nums)):
if j == i+1 or nums[j] != nums[j-1]:
# 需要保证j在k的左侧
while nums[i] + nums[j] + nums[k] > 0 and j<k:
k -= 1
# 如果指针重合,随着 b 后续的增加,就不会有满足 a+b+c=0 并且 b<c 的 c 了,可以退出循环
if j == k:
break
if nums[i] + nums[j] + nums[k] == 0:
result.append([nums[i], nums[j], nums[k]])
return result
复杂度分析
- 时间复杂度: O ( N 2 ) O(N^2) O(N2),其中 N N N 是数组 nums \textit{nums} nums 的长度。
- 空间复杂度: O ( log N ) O(\log N) O(logN)。我们忽略存储答案的空间,额外的排序的空间复杂度为 O ( log N ) O(\log N) O(logN)。然而我们修改了输入的数组 nums \textit{nums} nums,在实际情况下不一定允许,因此也可以看成使用了一个额外的数组存储了 nums \textit{nums} nums的副本并进行排序,空间复杂度为 O ( N ) O(N) O(N)。