1、什么是双指针
双指针即用两个不同速度或不同方向的指针对数组或链表进行访问,给两个不同指针添加特定的判断条件从而达到特定的目的。
2、双指针如何解决问题
在时间或空间条件有限的情况下使用一个指针遍历需要消耗大量的时间或者根本无法解决问题,这时候就需要我们使用双指针,通过给双指针添加特定判断条件来看是否达到条件.
双指针分为快慢指针和左右指针,左右指针通常在数组有序的情况下使用,快慢指针通常在单向遍历需要消耗大量时间,或者有特定要求限制的情况下使用。
常见的双指针方式
同速指针:链表上两个指针,一个先出发,另一个后出发并以相同的速度跟随;
数组上的两个指针指针在数组两端(左右指针),同时同速度出发,直至相遇.
例子:
二分查找:左右指针分别从数组两端向对方移到,直到相遇就找到了.
删除链表倒数第n个元素:先让其中一个指针向前走k步,接着两个指针以同样的速度一起
向前进,直到前面的指针走到尽头了,则后面的指针即为倒数第k个元素
快慢指针:链表上两个指针从同一节点出发,其中一个指针前进速度比另一个指针快
例子:
计算链表的中点:快慢指针从头节点出发,每轮迭代中,快指针向前移动两个节点,慢
指针向前移动一个节点,最终当快指针到达终点的时候,慢指针刚好在中间的节点
1其它例子如判断链表是否有环,求链表中环的长度!
下面我们来做几道例子:
1.左右指针:

class Solution {
public int search(int[] nums, int target) {
//1.暴力做法
// int len=nums.length;
// for(int i=0;i<len;i++){
// if(nums[i]==target){
// return i;
// }
// }
// return -1;
//2.二分查找算法
int len=nums.length;
int l=0; //定义左指针
int r=len-1;//定义右指针
while(l<=r){
int mid=(r-l)/2+l;
if(target < nums[mid]){
r=mid-1;
}else if(target > nums[mid]){
l=mid+1;
}else{
return mid;
}
}
return -1;
}
}
2.删除链表倒数第n个元素:

class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode preh=new ListNode(-1,head);//哑结点,即指向头结点
ListNode first=head;//指针first先走n步
ListNode second=preh;
for(int i=0;i<n;i++) first=first.next;
while(first != null){
first=first.next;
second=second.next;
}
second.next=second.next.next;
return preh.next;
}
}
3.计算链表的中点:

class Solution {
public ListNode middleNode(ListNode head) {
//快慢指针
ListNode fast=head,slow=head;
while( fast != null && fast.next != null ){
//判断条件: 一定要把fast != null 放在fast.next!= null的前面
//防止fast为空时,fast.next无法找到的错误
slow = slow.next;
fast=fast.next.next;
}
return slow;
}
}
例子就写到这里,剩下的