大家都喜欢将双指针分为两类,一类是快慢指针,另一类是左右指针;
其中,快慢指针主要解决一些和链表相关的问题,左右指针主要解决一些数组和字符串的问题,比如二分查找这样的。
快慢指针
快慢指针在使用的时候一般都是初始化指向链表的头部,之所以有快有慢是因为后面在更新的时候跨度不一样;
快慢指针可以用来判断一个链表中是否含有环的问题,下面一起来看一下这个问题:
对于一个链表来说,每个结点知道下一个结点是啥,所有我们如果只采用一个指针的话并不能做到判断是否有环;一般这种问题通常是使用快慢指针来解决,设置两个指针,一个跑得快,一个跑得慢,如果链表中不含有环的话,那么跑得快的指针最终会指向null;如果链表中含有环的话,那么会出现快指针超过慢指针一圈的情况;
具体的代码如下所示:
public boolean check(Node head){
Node fast,slow;
fast=fast.next.next;
fast=slow=head;
while(fast!=null&&fast.next!=null){
fast=fast.next.next;
slow=slow.next;
if(fast==slow)
return true;
}
return false;
}
第二个应用是可以用来寻找链表的中点,代码如下所示:
public Node fun(Node head){
Node fast,slow;
fast=slow=head;
while(fast!=null&&fast.next!=null){
fast=fast.next.next;
slow=slow.next;
}
return slow;
}
左右指针
左右指针大多数在应用的时候就是两个索引值,一个在左,一个在右;当然并不绝对,也有的是两个指针初始化时都在左边,也就是从前向后,也有的情况下需要从后往前进行应用;
二分查找就是左右指针的一个应用,和其他方式的使用主要区别就是如何更新左右指针的索引值,下面介绍两个左右指针的应用实例,感受一下区别所在:
问题1:给定一个升序排列的有序数组,找到两个数使得它们相加之和等于目标数,最后返回这两个数的索引值。
具体代码如下:
public int[] fun(int []nums,int target){
int left=0;
int right=nums.length-1;
while(left<=right){
if(nums[left]+nums[right]==target)
return new int[]{left,right};
else if(sum<target)
left++;
else if(sum>target)
right++;
}
return new int[]{-1,-1};
}
问题2:给定一个数组进行反转;
具体的代码如下:
public void fun(int []nums,int target){
int left=0;
int right=nums.length-1;
while(left<=right){
int temp=nums[left];
nums[left]=nums[right];
nums[right]=temp;
left++;
right--;
}
}