141. 环形链表 及其相关

发布时间 2023-06-20 21:53:29作者: Chenyi_li

141. 环形链表

1.哈希表法:

将节点依次加入set,如果有重复就是有环。

public class Solution {
    public boolean hasCycle(ListNode head) {
        Set<ListNode> set = new HashSet<ListNode>();
        while(head!=null){
            if(!set.add(head)){
                return true;
            }
            head = head.next;
        }

        return false;
    }
}

2.快慢指针

public class Solution {
    public boolean hasCycle(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;
        while(fast!=null&&fast.next!=null){
            slow = slow.next;
            fast = fast.next.next;
            if(slow==fast){
                return true;
            }
        }

        return false;
    }
}

如果有环,快慢指针迟早都会进入环,只要快指针比慢指针快1步,迟早能追上,而不会跨过。同理慢指针两步。快指针三步也可以。

//如下,快指针三步,慢指针两步。
public class Solution {
    public boolean hasCycle(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;
        while(fast!=null&&fast.next!=null&&fast.next.next!=null){
            slow = slow.next.next;
            fast = fast.next.next.next;
            if(slow==fast){
                return true;
            }
        }

        return false;
    }
}

环形链表 II https://leetcode.cn/problems/linked-list-cycle-ii/solutions/12616/linked-list-cycle-ii-kuai-man-zhi-zhen-shuang-zhi-/

哈希表简单容易理解,就是空间复杂度是O(N)

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        Set<ListNode> set = new HashSet<ListNode>();
        ListNode t = head;
        while(t!=null){
            if(set.contains(t)){
                return t;
            }else{
                set.add(t);
            }
            t = t.next;
        }
        return null;
    }
}

双指针

参考大神:
作者:Krahets
链接:https://leetcode.cn/problems/linked-list-cycle-ii/solutions/12616/linked-list-cycle-ii-kuai-man-zhi-zhen-shuang-zhi-/

public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode fast = head, slow = head;
        while (true) {
            if (fast == null || fast.next == null) return null;
            fast = fast.next.next;
            slow = slow.next;
            if (fast == slow) break;
        }
        fast = head;
        while (slow != fast) {
            slow = slow.next;
            fast = fast.next;
        }
        return fast;
    }
}

注意:如果慢指针是两步,快指针是三步,也是可以的。相当于f=3/2s f = s+nb 消完后还是可以的,能通过测试用例

public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode fast = head, slow = head;
        while (true) {
            if (fast == null || fast.next == null||fast.next.next == null) return null;
            fast = fast.next.next.next;
            slow = slow.next.next;
            if (fast == slow) break;
        }
        fast = head;
        while (slow != fast) {
            slow = slow.next;
            fast = fast.next;
        }
        return fast;
    }
}