快慢指针,如果链表存在有环,快指针fast
一定会追上慢指针slow
。
因为当 fast
从后面接近slow
时, 有两种可能性:
所以:
n+1-2
即n-1
步。重复这个过程,直到快指针和慢指针相遇。所以, 如果链表有环, 快指针一定会追上慢指针, 二者相遇。
通常设定快指针比慢指针多走一步,减少访问链表的频率。
slow 和 fast 最初设定不能都等于head
这道题不同于234. 回文链表
234. 回文链表是去找到链表的中点
这道题是去看有无环,用快慢指针做,最终两指针相遇。
while
循环的终止条件为slow != fast
如果一开始slow = head; fast = head;
则循环不进行,与目的不符合。
最多遍历一遍链表的n个节点
总计为O(n)
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public boolean hasCycle(ListNode head) {
//当无节点或者只有一个节点
if(head == null || head.next == null){
return false;
}
//定义起点位置,相当于同一起跑线,不影响后面的步数之差
//2个节点以上,包含环,用快慢指针
ListNode slow = head;
ListNode fast = head.next;
//还没有相遇时
while(slow != fast){
//快指针跑得比慢指针快,先让他去判断
if(fast == null || fast.next == null){
return false;
}
slow = slow.next;//走一步
fast = fast.next.next;//走两步
}
return true;
}
}
先判断为空链表的情况(递归的基值)
l1
为空链表则返回l2
l2
为空链表则返回l1
l1
的值 < l2
的值 则l1
的下一个节点指向l2
l1
的值 >= l2
的值 则l2
的下一个节点指向l1