「算法」環(huán)形鏈表 & 環(huán)形鏈表 II

00141 環(huán)形鏈表

題目描述

給定一個鏈表,判斷鏈表中是否有環(huán)。

實例 1:

輸入:head = [3,2,0,-4], pos = 1
輸出:true
解釋:鏈表中有一個環(huán),其尾部連接到第二個節(jié)點。

示例 2:

輸入:head = [1,2], pos = 0
輸出:true
解釋:鏈表中有一個環(huán),其尾部連接到第一個節(jié)點。

示例 3:

輸入:head = [1], pos = -1
輸出:false
解釋:鏈表中沒有環(huán)。

力扣地址

解題報告

哈希表

本題解由微信公眾號小猿刷題提供, 錯誤之處, 歡迎指正.

通過檢查一個結點此前是否被訪問過來判斷鏈表是否為環(huá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) {
        Set<ListNode> nodesSeen = new HashSet<>();
        while (head != null) {
            if (nodesSeen.contains(head)) {
                return true;
            } else {
                nodesSeen.add(head);
            }
            head = head.next;
        }
        return false;
    }
}

雙指針

本題解由微信公眾號小猿刷題提供, 錯誤之處, 歡迎指正.

定義兩個不同速度的快、慢指針遍歷鏈表,慢指針每次移動一步,而快指針每次移動兩步。如果列表中不存在環(huán),最終快指針將會最先到達尾部,此時我們可以返回 false

/**
 * 微信公眾號"小猿刷題"
 * 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) {
        // 從鏈表頭部開始
        ListNode slow = head;
        ListNode fast = head;
        while(fast != null && fast.next != null){
            // 快慢指針行走
            fast = fast.next.next;
            slow = slow.next;
            // 相遇說明有環(huán)
            if(slow == fast){
                return true;
            }
        }
        return false;
    }
}
小猿刷題

00142 環(huán)形鏈表 II

題目描述

給定一個鏈表,返回鏈表開始入環(huán)的第一個節(jié)點。 如果鏈表無環(huán),則返回 null。

為了表示給定鏈表中的環(huán),我們使用整數(shù) pos 來表示鏈表尾連接到鏈表中的位置(索引從 0 開始)。 如果 pos 是 -1,則在該鏈表中沒有環(huán)。

說明:不允許修改給定的鏈表。

示例 1:

輸入:head = [3,2,0,-4], pos = 1
輸出:tail connects to node index 1

解釋:鏈表中有一個環(huán),其尾部連接到第二個節(jié)點。

image

示例 2:

輸入:head = [1,2], pos = 0
輸出:tail connects to node index 0

解釋:鏈表中有一個環(huán),其尾部連接到第一個節(jié)點。

image

示例 3:

輸入:head = [1], pos = -1
輸出:no cycle

解釋:鏈表中沒有環(huán)。

image

進階:

  • 你是否可以不用額外空間解決此題?

力扣地址

解題報告

哈希表

本題解由微信公眾號小猿刷題提供, 錯誤之處, 歡迎指正.

如果我們用一個 Set 保存已經訪問過的節(jié)點,我們可以遍歷整個列表并返回第一個出現(xiàn)重復的節(jié)點

/**
 * 微信公眾號"小猿刷題"
 * 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> visited = new HashSet<ListNode>();

        ListNode node = head;
        while (node != null) {
            if (visited.contains(node)) {
                return node;
            }
            visited.add(node);
            node = node.next;
        }

        return null;
    }
}

雙指針

本題解由微信公眾號小猿刷題提供, 錯誤之處, 歡迎指正.

圖解快慢指針判斷環(huán)&環(huán)入口算法.

環(huá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) {
        ListNode fast = head;
        ListNode slow = head;
        while(fast != null && fast.next != null){
            fast = fast.next.next;  // 快指針移動2位
            slow = slow.next;       // 慢指針移動1位
            // 快慢指針的處理只能判斷是否有環(huán),并不能判斷出在哪里出現(xiàn)的環(huán)(相遇說明有環(huán))
            if(fast == slow){
                fast = head;
                // 重置快指針, 然后各自都移動1位,再次相遇的地方就是環(huán)入口
                while(slow != fast){
                    fast = fast.next;
                    slow = slow.next;
                }
                return fast;
            }
        }
        return null;
    }
}
小猿刷題
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
禁止轉載,如需轉載請通過簡信或評論聯(lián)系作者。

相關閱讀更多精彩內容

友情鏈接更多精彩內容