4.双指针技巧

一、快、慢指针的常用算法

		快、慢指针 一般会 初始化 链表头节点head ,前进时 快指针 fast 在前面,慢指针 slow 在后,可以巧妙解决一些 链表中的问题

1.判断链表中是否有环?(LeetCode 141题 难度:简单 )

		如果有环的话,快指针必定超越慢指针 一圈, 然后相交。
		如果没有环 快指针 终有 一时刻 == null 的时候,那么 return false;

如图:

2.已知链表中有环,判断起始位置(LeetCode 142题:难度:中等)

public ListNode detectCycle(ListNode head) {  
   ListNode fast,slow;  
   fast=slow=head;  
   while(fast!=null&&fast.next!=null){  
       //找到相交的位置  
 fast=fast.next.next;  
       slow=slow.next;  
       if(fast==slow){  
           break;  
       }  
   }  
   //慢指针回到 头部  
 slow=head;  
   while(slow!=fast){  
       //两个指针以同样的速度前进  
 fast=fast.next;  
       slow=slow.next;  
   }  
   //两个指针相遇的地方就是起点  
 return fast;  
}

可以看到,当快慢指针相遇的时候,让其中的一个指针 回到头部,再以相同的速度前进,再次相遇的时候就是 起始点 ,这是为什么?

① 第一次相遇的时候,假设 slow 走了k步,那么 fast 一定走了 2k 步,也就是 比slow 多 走了 k 步

② 设相遇点距环的起点的距离为 m,那么环的起点距头结点 head 的距离为 k - m,也就是说如果从 head 前进 k - m 步就能到达环起点。

③ 然后 动动脑筋 就解决了 。

3.无环链表的中点(LeetCode 142题:难度:中等)

	思路:快指针 走完全程, 慢指针 走一半.
while(fast!=null&&fast.next!=null){  
    fast=fast.next.next;  
    slow=slow.next;  
}  
//slow 就到中间位置了  
return slow;

当链表的长度为 奇数的时候 ,slow 恰巧停在中间位置,
当链表的长度为偶数的时候,slow停在 中间偏右的位置

这没什么好说的啦

4.单链表中倒数第K个节点(剑指offer 22题 难度:简单)

	思路:
		找差值,快指针先走,快 慢指针相差 k个循环,然后当 fast 到最后的时候,要查找的节点就是 慢指针对应的节点

代码就不演示啦

二、左、右指针常用算法

二分搜索(LeetCode 704题 难度:简单)

两数之和(LeetCode 1题 难度:简单)

反转数组

滑动窗口算法

posted @ 2021-07-04 18:38  宋佳强  阅读(67)  评论(0编辑  收藏  举报