1.单词循环找到数组倒数第n个数字
如LeetCode19题.删除链表的倒数第N个结点
当有要求只遍历数组一次的时候,快慢指针就是个非常不错的应用场景。先让快指针走过N个点,此时慢指针从头开始走。这样一来,当快指针走到头的时候,慢指针正好走到倒数第N-1个结点。
通俗点讲就是快的先走了几步,等快的到头了,慢的就还剩几步没走。
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode slow=head,fast=head;
if(head==null) return null;
for(int i=0;i<n;i++){
fast=fast.next;
}
if(fast==null) return head.next;
while(fast.next != null){
slow=slow.next;
fast=fast.next;
}
slow.next=slow.next.next;
return head;
}
2.链表中存在环形,如何找到入口
如LeetCode142题环形链表 II,LeetCode287题寻找重复数字
可以使用快慢指针判断链表中是否存在环形。让慢指针每次走一步,快指针每次走两步。这样,若链表中存在环形的时候,快慢指针一定会在环形链表中的某个位置相遇。即slow=fast;假设相遇的时候慢指针走了n步,表头到重复元素即入口的距离为m步,环的周长为c。那么快指针一共走了2n步,由于快慢指针在环里相遇即n是c的整数倍。慢指针在环里走的距离为n-m。那么我们设置第三个指针finder,它从起点开始和slow(在fast和slow相遇处)同步前进,当finder和slow相遇时,就是在环的入口处相遇,也就是重复的那个数字相遇。
public int findDuplicate(int[] nums) {
int slow=0,fast=0;
while(true){
fast = nums[nums[fast]];
slow = nums[slow];
if(fast == slow)
break;
}
int help=0;
while(true){
slow=nums[slow];
help=nums[help];
if(help == slow)
break;
}
return help;
}