LeetCode142——环形链表II

版权声明:我的GitHub:https://github.com/617076674。真诚求星! https://blog.csdn.net/qq_41231926/article/details/86105434

我的LeetCode代码仓:https://github.com/617076674/LeetCode

原题链接:https://leetcode-cn.com/problems/linked-list-cycle-ii/description/

题目描述:

知识点:哈希表、双指针、链表

思路一:用一个hashSet来存储已经遍历过的节点

本题是LeetCode141——环形链表的加强版。

一旦发现某个节点的next节点已经被遍历过,则说明存在环,直接返回该next节点即可。否则,返回null。

时间复杂度和空间复杂度均是O(n),其中n为链表中的节点个数。

JAVA代码:

public class Solution {
    public ListNode detectCycle(ListNode head) {
        HashSet<ListNode> hashSet = new HashSet<>();
        ListNode dummyHead = new ListNode(-1);
        dummyHead.next = head;
        ListNode cur = dummyHead;
        while(null != cur.next){
            if(hashSet.contains(cur.next)){
                return cur.next;
            }
            cur = cur.next;
            hashSet.add(cur);
        }
        return null;
    }
}

LeetCode解题报告:

思路二:用快慢双指针遍历链表

快指针一次移动两步,慢指针依次移动一步。将快慢双指针想象成两个运动员在赛跑,如果链表有环,那么终有一个时刻快慢双指针会重合。一旦某个节点的next节点出现null,说明不是环形链表,直接返回null即可。

如果是环形链表,我们令其中一个指针指向虚拟头节点,而另一个指针则仍然在相遇的那个节点,一起移动这两个指针,直到这两个指针相遇,这个新的相遇点就是链表开始入环的第一个节点。

为什么上述算法得到的点就是链表开始入环的第一个节点呢?

如上图所示,虚拟头节点到第一个入环的节点的距离是x1,第一个入环的节点顺时针出发到相遇点的距离是x2,相遇点顺时针出发到第一个入环的节点的距离是x3。

从dummyHead节点出发到快慢指针相遇的过程中:

第一个慢指针走过的路程长度是x1 + x2

第二个快指针走过的路程长度是x1 + x2 + x3 + x2

由快慢指针的速度关系得:(x1 + x2) * 2 = x1 + x2 + x3 + x2,因此x1 = x3。因此,我们只需令其中一个指针指向虚拟头节点,而另一个指针则仍然在相遇的那个节点,一起移动这两个指针,直到这两个指针相遇,这个新的相遇点就是链表开始入环的第一个节点。

时间复杂度是O(n),其中n为链表中的节点个数。空间复杂度是O(1)。

JAVA代码:

public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode dummyHead = new ListNode(-1);
        dummyHead.next = head;
        ListNode cur1 = dummyHead;
        ListNode cur2 = dummyHead;
        while(true){
            if(null == cur2.next || null == cur2.next.next){
                return null;
            }
            cur1 = cur1.next;
            cur2 = cur2.next.next;
            if(cur1 == cur2){
                break;
            }
        }
        cur1 = dummyHead;
        while(cur1 != cur2){
            cur1 = cur1.next;
            cur2 = cur2.next;
        }
        return cur1;
    }
}

LeetCode解题报告:

猜你喜欢

转载自blog.csdn.net/qq_41231926/article/details/86105434