一、双指针简介
- 双指针主要用于遍历数组,两个指针指向不同的元素,从而协同完成任务。
- 双指针可以从不同的方向向中间逼近也可以朝着同一个方向遍历。
变异的双指针
有时候,我们能很容易看出来题目是双指针类型的变异,但是直接使用双指针的话又不行。就会不知觉的想到,难道要用三指针?四指针?(饶饶我吧,四指针我也不会啊)。所以这时,我们可以在双指针的基础上使用其他的数据结构,例如说哈希表、数组等。或者是多加一层循环
二、例题
1. leetcode 15 三数之和
题解思路参考
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,
使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
排序 + 双指针
本题的难点在于如何去除重复解。
算法流程:
特判,对于数组长度 nn,如果数组为 nullnull 或者数组长度小于 33,返回 [][]。
对数组进行排序。
遍历排序后数组:
若 nums[i]>0nums[i]>0:因为已经排序好,所以后面不可能有三个数加和等于 00,直接返回结果。
对于重复元素:跳过,避免出现重复解
令左指针 L=i+1L=i+1,右指针 R=n-1R=n−1,当 L<RL<R 时,执行循环:
当 nums[i]+nums[L]+nums[R]== 0,执行循环,判断左界和右界是否和下一位置重复,去除重复解。并同时将 L,RL,R 移到下一位置,寻找新的解
若和大于 0,说明 nums[R] 太大,R 左移
若和小于 0,说明 nums[L] 太小,L 右移
作者:zhu_shi_fu
链接:https://leetcode-cn.com/problems/3sum/solution/pai-xu-shuang-zhi-zhen-zhu-xing-jie-shi-python3-by/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/3sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2. (变异双指针) leetcode 18 四数之和
- 题目:
给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。(来源leetcode)
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
if(not nums or len(nums) < 4):
return []
n = len(nums)
# 结果
res = []
# 排序
nums.sort()
for i in range(n-3):
# 加快判断,获取最小值
if(target < nums[i]+nums[i+1]+nums[i+2]+nums[i+3]):
break
# 加快判断,获取最大值
if(target > nums[i]+nums[n-1]+nums[n-2]+nums[n-3]):
continue
# 避免重复
if(i > 0 and nums[i] == nums[i-1]):
continue
for j in range(i+1, n-2):
# 加快判断,获取最小值
if(target < nums[i]+nums[j]+nums[j+1]+nums[j+2]):
break
# 加快判断,获取最大值
if(target > nums[i]+nums[j]+nums[n-1]+nums[n-2]):
continue
# 避免重复
if(j > i+1 and nums[j] == nums[j-1]):
continue
L = j + 1
R = n - 1
while(L < R):
tmp = nums[i]+nums[j]+nums[L]+nums[R]
if(tmp > target):
R = R- 1
elif(tmp < target):
L = L + 1
else:
res.append([nums[i],nums[j],nums[L],nums[R]])
# 防止重复
while(L < R and nums[L] == nums[L+1]):
L = L + 1
while(L < R and nums[R] == nums[R-1]):
R = R - 1
L = L + 1
R = R - 1
return res
3. 链表是否有环、环的节点(考虑到速度差)等
(后续有时间了再进行补充)
写在最后
如果觉得本文对你有帮助的话,可以为我点个赞哈,你的关注和支持是我坚持下去最大的鼓励。
新手上路,对文章有什么建议和意见,也欢迎留言告诉我,期待你的回馈。