LeetCode.141 環形鏈表

這是我參與8月更文挑戰的第5天,活動詳情查看:8月更文挑戰html

題目描述:

141. 環形鏈表 - 力扣(LeetCode) (leetcode-cn.com)算法

給定一個鏈表,判斷鏈表中是否有環。markdown

若是鏈表中有某個節點,能夠經過連續跟蹤 next 指針再次到達,則鏈表中存在環。 爲了表示給定鏈表中的環,咱們使用整數 pos 來表示鏈表尾鏈接到鏈表中的位置(索引從 0 開始)。 若是 pos-1,則在該鏈表中沒有環。注意:pos 不做爲參數進行傳遞,僅僅是爲了標識鏈表的實際狀況。app

若是鏈表中存在環,則返回 true 。 不然,返回 falseide

進階:oop

你能用  O ( 1 ) O(1) (即,常量)內存解決此問題嗎?post

示例一

image.png

輸入: head = [3,2,0,-4], pos = 1
輸出: true
解釋: 鏈表中有一個環,其尾部鏈接到第二個節點。
複製代碼

示例二

image.png

輸入: head = [1,2], pos = 0
輸出: true
解釋: 鏈表中有一個環,其尾部鏈接到第一個節點。
複製代碼

示例三

image.png

輸入: head = [1], pos = -1
輸出: false
解釋: 鏈表中沒有環。
複製代碼

思路分析

節點計數法

最容易的就是遍歷鏈表了,循環訪問每一個列表,存入HashSet,利用HashSet不可重複的特性,若是咱們添加節點失敗,就說明這個節點以前添加過,天然就是有環的,反之無環。動畫

AC代碼

class Solution {
    fun hasCycle(head: ListNode?): Boolean {
        val set = mutableSetOf<ListNode>()
        var p = head
        while (null != p) {
            if (!set.add(p)) {
                return true
            }
            p = p.next
        }
        return false
    }
}
複製代碼

快慢指針

要判斷列表中是否有環,能夠定義一個慢指針slow指向鏈表的頭結點,快指針fast指向頭結點的下一個結點。而後,慢指針slow每次向前移動一個位置,快指針fast每次向前移動兩個位置。這樣,若是鏈表中存在環,快指針就會先進入環,而後追上慢指針。ui

具體思路,可參考此題解中的動畫演示:lua

AC代碼

class Solution {
    fun hasCycle(head: ListNode?): Boolean {
        if (null == head || null == head?.next) {
            return false
        }
        var slow = head
        var fast = head?.next
        while (slow != fast) {
            if (null == fast || null == fast?.next) {
                return false
            }
            slow = slow?.next
            fast = fast?.next?.next
        }
        return true
    }
}
複製代碼

總結

摘自官解

「Floyd 判圈算法」(又稱龜兔賽跑算法)

假想「烏龜」和「兔子」在鏈表上移動,「兔子」跑得快,「烏龜」跑得慢。當「烏龜」和「兔子」從鏈表上的同一個節點開始移動時,若是該鏈表中沒有環,那麼「兔子」將一直處於「烏龜」的前方;若是該鏈表中有環,那麼「兔子」會先於「烏龜」進入環,而且一直在環內移動。等到「烏龜」進入環時,因爲「兔子」的速度快,它必定會在某個時刻與烏龜相遇,即套了「烏龜」若干圈。

咱們能夠根據上述思路來解決本題。具體地,咱們定義兩個指針,一快一滿。慢指針每次只移動一步,而快指針每次移動兩步。初始時,慢指針在位置 head,而快指針在位置 head.next。這樣一來,若是在移動的過程當中,快指針反過來追上慢指針,就說明該鏈表爲環形鏈表。不然快指針將到達鏈表尾部,該鏈表不爲環形鏈表。

若是咱們知道這個算法的話,那麼要求的進階答案其實就迎刃而解了。

參考

環形鏈表 - 環形鏈表 - 力扣(LeetCode) (leetcode-cn.com)

動畫演示 快慢指針 #141環形鏈表 - 環形鏈表 - 力扣(LeetCode) (leetcode-cn.com)

擴展閱讀

一文搞定常見的鏈表問題 (歡迎交流 - 環形鏈表 - 力扣(LeetCode) (leetcode-cn.com)

相關文章
相關標籤/搜索