目录
前言
最近都在学习算法。突然想起来我这里有发布文章,都是为了巩固知识做的。所以现在我也写一篇吧。学算法3个月了,最先接触的算法就是这个双指针。很经典,也很简单。希望文章可以帮助到各位。
一、双指针是什么?
首先我们要明白,双指针是什么东西。他很简单,说白了就是两个变量。有什么用呢?他就是为了能在数组中进行查找。比如我给你一个数组nums:
nums = [-5, -2, 0, 2, 3, 5]
现在要你在数组中找出有那两个数相加起来等于5,并返回其下标。当然说一下就是,双指针有很多种类型的。有相向的,有快慢的,有背向的等等。使用双指针的话,尽量保证数组有序。
那说了这么多,这个题目应该怎么解决呢?
我们可以先定义两个变量一个left一个right
让他们两个一个指向数组的头部,一个指向数组的尾部
python
nums = [-5, -2, 0, 2, 3, 5]
left = 0
right = len(nums) - 1
while left < right:
temp = nums[left] + nums[right]
if temp > 5:
right -= 1
elif temp < 5:
left += 1
else:
print(left, right)
break
那,这个代码的结果就是2 5,对应的值就是0 和 5。因为这里我说只要找到就行了。所以写了break,要是题目有其他需求的,可以不写break。这个就是很经典的双指针了。很好理解吧。^V^
二、例题
OK,现在讲一下我给的例题。我也是今天又来重做了一遍。有益于思考这个题目,可以多刷。
应该是可以直接使用的。这里我来说明一下。注释有什么问题可以问。我也没学多久,可以一起探讨学习。这里我就简单概括一下。题目是不是说要你找下标 i!=j!=k 这么三个元素。那么我们应该怎么做呢?第一,因为他的要求很宽松,所以任意三个元素都是可以的。那么直接强行遍历的话就是O(n**3)的时间复杂度。所以使用双指针是最优的解法。去除重复值可以使用到set,即哈希表,不是最优的写法,毕竟你都使用sort了。还多开一个空间。只是想到了,可以这么写。
python
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
n = len(nums)
if n < 3:
return []
if n == 3:
return [nums] if sum(nums) == 0 else []
ans = []
# 如果说要使用到sort的话,时间不可避免到nlogn
# 但是如果不使用sort的话,我的双指针就无法得到正确答案(因为他不能保证遍历到正确的数,会超时)
# 所以必须使用sort,这样可以避免时间n**3或n**2
nums.sort()
# 要去除重复数,这样就可以避免数组的重复,问题
# 也可以使用set,即哈希去记录,当然因为排序过,所以可以直接left+1跳过
# cnt = defaultdict(int)
# 枚举中间值,不需要预处理,因为已经使用了sort了
for i in range(n - 2):
# 留两个位置给另外两个数
# 然后在里面使用双指针
left = i + 1
right = n - 1
# 跳过重复的值,并进行剪枝
# 当当前的数,加上最大的两个数都到小于0,说明没救了
# 如果第一个数>0,后面所有数更大,不可能和为0
if nums[i] + nums[-2] + nums[-1] < 0:
continue
if nums[i] > 0:
break
# 加上前面两个数,都大于0,说明后面还有更大的数,直接break就好了
if nums[i] + nums[i + 1] + nums[i + 2] > 0:
break
if i > 0 and nums[i] == nums[i - 1]:
continue
while left < right:
temp = nums[left] + nums[right]
if temp + nums[i] == 0:
ans.append([nums[left], nums[i], nums[right]])
while left < right and nums[left] == nums[left + 1]:
left += 1
while left < right and nums[right] == nums[right - 1]:
right -= 1
right -= 1
left += 1
continue
if temp + nums[i] > 0:
right -= 1
continue
if temp + nums[i] < 0:
left += 1
return ans
作者:夜思红尘
链接:https://leetcode.cn/problems/3sum/solutions/3870602/xun-wei-01-by-chao-xi-7b-y4m3/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
总结
OKOK,有问题来问哈。多多刷题,编程才会有所提升。加油💪!