当遇到链表,数组,二叉树等问题中使用
主要使用场景就是
1.快慢指针,两个指针,一个步长大,一个步长小,或者两个指针不同步行走。适用问题有求两链表公共节点,求链表中是否存在环,求链表中点,链表反转,删除链表倒数节点等
2.对撞指针,两个指针分别指向数组的开头和结尾,通过循环来完成题目,多用于有序数组求和,或者求回文串等
3.滑动窗口,两个指针分别代表窗口的左边界和右边界,通过不断的移动左右指针来完成题目要求,多用于求连续子串或者子数列
1.快慢指针
(1)求中点
ListNode* fast = head; //快慢指针都指向头结点
ListNode* slow = head;
while(fast!=NULL&&fast->next!=NULL){ //当快指针为奇数时判断fast->next!=NULL
fast=fast->next->next; //为偶数求中间靠右节点时判断fast!=NULL
slow=slow->next; //快的走两步,慢的走一步
}
return slow; //返回慢指针
(2)翻转链表
ListNode* slow = NULL; //一开始慢节点指向空,快节点指向头结点
ListNode* fast = head; //这样做的好处是可以省去一些繁琐的特殊情况判断
while(fast){
ListNode* next = fast->next; //next作用是存储节点
fast->next=slow; //让当前节点指向自己上一个节点
slow=fast; //上一个节点后移
fast=next; //当前节点后移
}
return slow; //此时fast为空,slow为原本节点的尾结点,翻转链表的头结点
(3)求两链表公共节点
ListNode* a=headA;
ListNode* b=headB;
while(a!=b){
a=a->next;
b=b->next;
if(a==NULL&&a!=b){
a=headB;
}
if(b==NULL&&a!=b){
b=headA;
}
}
if(a==NULL) return NULL;
else return a;
}
//具体解释看题解 剑指 Offer II 023. 两个链表的第一个重合节点
(4)删除链表倒数节点
ListNode* fast=head;
ListNode* ans=new ListNode(0,head);
ListNode* slow=ans;
int i=0;
while(fast&&i<n){
fast=fast->next;
i++;
}
while(fast){
slow=slow->next;
fast=fast->next;
}
slow->next=slow->next->next;
return ans->next;
//具体解释看题解 剑指 Offer II 021. 删除链表的倒数第 n 个结点
(5)链表中环的开始节点
ListNode* fast=head;
ListNode* slow=head;
while(true){
if(fast==NULL||fast->next==NULL) return NULL;
fast=fast->next->next;
slow=slow->next;
if(fast==slow) break;
}
fast=head;
while(fast!=slow){
fast=fast->next;
slow=slow->next;
}
return fast;
//具体看题解 剑指 Offer II 022. 链表中环的入口节点
2.对撞指针
(1)回文串问题
(2)求n数和为目标值的问题
3.滑动窗口
int slow=0;
int fast=0;
int mmax=INT_MAX;
int sum=0;
while(fast<nums.size()){ //注意两个while循环的判断条件
sum+=nums[fast];
while(sum>=target){ //注意两个while循环的判断条件
mmax=min(mmax,fast-slow+1);
sum-=nums[slow++];
}
fast++;
}
if(mmax==INT_MAX) return 0;
else return mmax;
}
LeetCode: 167:两数之和 II(双指针)(对撞指针)
LeetCode: 剑指 Offer II 007. 数组中和为 0 的三个数(双指针)(对撞指针)
LeetCode: 18. 四数之和(双指针)(对撞指针)
LeetCode: 剑指 Offer II 019. 最多删除一个字符得到回文(双指针)(对撞指针)
LeetCode: 剑指 Offer II 021. 删除链表的倒数第 n 个结点(双指针)(快慢指针)
LeetCode: 剑指 Offer II 022. 链表中环的入口节点(map)(双指针)(快慢指针)
LeetCode: 剑指 Offer II 023. 两个链表的第一个重合节点(双指针)(快慢指针)
LeetCode: 剑指 Offer II 026. 重排链表(双指针)(快慢指针)
LeetCode: 剑指 Offer 59 - I. 滑动窗口的最大值(双指针)(固定长度滑动窗口)
LeetCode: 剑指 Offer II 008. 和大于等于 target 的最短子数组(双指针)(不定长度滑动窗口)