快慢双指针法
介绍
快慢双指针是双指针问题的一种解决方案,主要用于解决链表相关的题目,而左右指针那种滑动窗口的算法主要是用于解决数组问题
应用
- 快慢双指针可以用来判定链表中是否存在环
一般而言,如果链表中存在环路,那么对于单链表的遍历就会陷入死循环,可以使用快慢双指针去遍历该链表,慢指针一步一步走,快指针一次走两步;
那么如果快指针最终走到null节点,那么就是遍历完成;
如果存在环路,那么快慢指针最终一定会相遇,因为快指针始终快于慢指针一倍的距离
boolean hasCycle(ListNode head) {
ListNode fast, slow;
fast = slow = head;
while(fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
if (fast == slow)
return true;
}
return false;
}
- 找到链表中环路的起点
当快慢指针第一次相遇的时候,就可以确定链表中存在环路,如果让其中一个节点回到起点再让快慢指针以同样速度前进,那么再次相遇就是环起点
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 slow;
}
- 寻找链表中点
我们可以让快指针一次前进两步,慢指针一次前进一步,当快指针到达链表尽头时,慢指针就处于链表的中间位置。
ListNode slow, fast;
slow = fast = head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
// slow 就在中间位置
return slow;
当程序结束时,如果链表的长度是奇数时,slow 恰巧停在中点位置;如果长度是偶数,slow 最终的位置是中间偏右;可以利用这个方法去进行归并排序
- 寻找链表的倒数第k个节点
让快指针先走 k 步,然后快慢指针开始同速前进。这样当快指针走到链表末尾 null 时,慢指针所在的位置就是倒数第 k 个链表节点(假设 k 不会超过链表长度)
ListNode slow, fast;
slow = fast = head;
while (k-- > 0)
fast = fast.next;
while (fast != null) {
slow = slow.next;
fast = fast.next;
}
return slow;

浙公网安备 33010602011771号