leetcode双指针
双指针一般又分为3中应用
- 快慢指针
- 碰撞指针
- 滑动窗口
快慢指针
判断链表是否有环
一快一慢 F和 S 相遇的话就是 成环 没有相遇就是没成环
判断链表中环的起点
链表中证明了 F指针一定比慢指针多走n圈环的长度
F = S+nb
F = 2*S
可以得到 S = nb
这个时候 如果再走链表起点到环起点的a步的话 也就是 环的起点
所以我们用F指针重新指向链表的起点 再次相遇的地方就是环的起点
碰撞指针
一般都是排好序的数组或链表
- 二分查找问题
- n数之和问题:比如两数之和问题,先对数组排序然后左右指针找到满足条件的两个数。如果是三数问题就转化为一个数和另外两个数的两数问题。以此类推。
四数之和
两个for循环用做外循环
用来循环 两个数 碰撞指针 是用来比较大小的
找到合适之后 放入hashmap中去重
class Solution {
public List<List<Integer>> fourSum(int[] nums, int target) {
List<List<Integer>> res = new ArrayList<List<Integer>>();
Arrays.sort(nums);
// Set<int []> set = new HashSet<>(Arrays.equals(new));
HashMap<String,ArrayList<Integer>> hm = new HashMap<>();
for(int i =0;i<nums.length-3;i++)
for(int j =i+1;j<nums.length-2;j++)
{
int left = j+1;
int right = nums.length-1;
while(left<right)
{
int sum = nums[i]+nums[j]+nums[right]+ nums[left];
if(sum == target){
ArrayList<Integer> arraylist = new ArrayList();
Integer [] tmp = new Integer[]{nums[i],nums[j],nums[right],nums[left]};
Arrays.sort(tmp);
Collections.addAll(arraylist,tmp);
if(!hm.containsKey(inttoString(tmp))) {
hm.put(inttoString(tmp),arraylist);
res.add(arraylist);
}
right--;
left++;
}
else if(sum <target)
{
left++;
}
else{
right--;
}
}
}
return res;
}
public static String inttoString(Integer [] ints)
{
String res ="";
for (int i = 0; i <ints.length ; i++) {
res = res+ints[i];
}
return res;
}
}
颜色分类
p0 代表 0的右边界
p2 代表 2 的左边界
cur代表当前的处理元素
算法
初始化0的最右边界:p0 = 0。在整个算法执行过程中 nums[idx < p0] = 0.
初始化2的最左边界 :p2 = n - 1。在整个算法执行过程中 nums[idx > p2] = 2.
始化当前考虑的元素序号 :curr = 0.
While curr <= p2 :
若 nums[curr] = 0 :交换第 curr个 和 第p0个 元素,并将指针都向右移。
若 nums[curr] = 2 :交换第 curr个和第 p2个元素,并将 p2指针左移 。
若 nums[curr] = 1 :将指针curr右移。
实现
class Solution {
public void sortColors(int[] nums) {
int cur =0; //要考虑的当前元素
int left = 0; //指向0的有边界
int right = nums.length-1;//指向 1的左边界
while(cur<=right){
if(nums[cur]==0)
{
swap(nums,cur,left);
left++;
cur++;
}
else if(nums[cur] ==1)
{
cur++;
}
else{
swap(nums,cur,right);
right--;
// cur++;
}
}
}
public void swap(int a[] ,int i,int j)
{
int tmp = a[i];
a[i] =a[j];
a[j] = tmp;
}
}
滑动窗口法
两个指针,一前一后组成滑动窗口
1、字符串匹配问题
2、子数组问题
992 K 个不同整数的子数组
这是一个典型的子数组问题 结合了hashmap 和 双指针 和 动态规划的问题 是一道极其综合的难题
最小覆盖子串
滑动窗口问题