1. ?LeetCode刷題實戰(zhàn)142: 環(huán)形鏈表 II

        共 2339字,需瀏覽 5分鐘

         ·

        2021-01-04 20:30

        算法的重要性,我就不多說了吧,想去大廠,就必須要經(jīng)過基礎(chǔ)知識和業(yè)務(wù)邏輯面試+算法面試。所以,為了提高大家的算法能力,這個公眾號后續(xù)每天帶大家做一道算法題,題目就從LeetCode上面選 !

        今天和大家聊的問題叫做?環(huán)形鏈表 II,我們先來看題面:
        https://leetcode-cn.com/problems/linked-list-cycle-ii/

        Given a linked list, return the node where the cycle begins. If there is no cycle, return null.


        There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the next pointer. Internally, pos is used to denote the index of the node that tail's next pointer is connected to. Note that pos is not passed as a parameter.


        Notice that you should not modify the linked list.

        題意


        給定一個鏈表,返回鏈表開始入環(huán)的第一個節(jié)點。 如果鏈表無環(huán),則返回 null。
        為了表示給定鏈表中的環(huán),我們使用整數(shù) pos 來表示鏈表尾連接到鏈表中的位置(索引從 0 開始)。 如果 pos 是 -1,則在該鏈表中沒有環(huán)。注意,pos 僅僅是用于標(biāo)識環(huán)的情況,并不會作為參數(shù)傳遞到函數(shù)中。
        說明:不允許修改給定的鏈表。
        進階:
        你是否可以使用 O(1) 空間解決此題?

        樣例


        解題

        思路:用快慢雙指針遍歷鏈表

        快指針一次移動兩步,慢指針依次移動一步。將快慢雙指針想象成兩個運動員在賽跑,如果鏈表有環(huán),那么終有一個時刻快慢雙指針會重合。一旦某個節(jié)點的next節(jié)點出現(xiàn)null,說明不是環(huán)形鏈表,直接返回null即可。
        如果是環(huán)形鏈表,我們令其中一個指針指向虛擬頭節(jié)點,而另一個指針則仍然在相遇的那個節(jié)點,一起移動這兩個指針,直到這兩個指針相遇,這個新的相遇點就是鏈表開始入環(huán)的第一個節(jié)點。
        為什么上述算法得到的點就是鏈表開始入環(huán)的第一個節(jié)點呢?
        如上圖所示,虛擬頭節(jié)點到第一個入環(huán)的節(jié)點的距離是x1,第一個入環(huán)的節(jié)點順時針出發(fā)到相遇點的距離是x2,相遇點順時針出發(fā)到第一個入環(huán)的節(jié)點的距離是x3。
        從dummyHead節(jié)點出發(fā)到快慢指針相遇的過程中:
        第一個慢指針走過的路程長度是x1 + x2 + k1 * (x2?+ x3)
        第二個快指針走過的路程長度是x1 + x2 + k2 * (x2?+ x3)。
        由快慢指針的速度關(guān)系得:(x1 + x2) * 2?+ 2 * k1 * (x2 + x3) = x1 + x2 + k2 * (x2?+ x3),因此x1 + x2 = (k2 - 2 * k1) * (x2 + x3),進而有x1 - x3 = (k2 - 2 * k1 - 1) * (x2 +?x3)。這說明x1和x3的距離差值剛好是環(huán)長(x2 + x3)的整數(shù)倍。因此,我們只需令其中一個指針指向虛擬頭節(jié)點,而另一個指針則仍然在相遇的那個節(jié)點,一起移動這兩個指針,直到這兩個指針相遇,這個新的相遇點就是鏈表開始入環(huán)的第一個節(jié)點。
        時間復(fù)雜度是O(n),其中n為鏈表中的節(jié)點個數(shù)??臻g復(fù)雜度是O(1)。

        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;
        ????}
        }


        好了,今天的文章就到這里,如果覺得有所收獲,請順手點個在看或者轉(zhuǎn)發(fā)吧,你們的支持是我最大的動力。

        上期推文:

        LeetCode1-140題匯總,希望對你有點幫助!
        LeetCode刷題實戰(zhàn)141: 環(huán)形鏈表


        瀏覽 48
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
          
          

            1. 91变态视频 | 国产又大又粗的视频 | 国产午夜性爽视频男人的天堂 | 日本亚洲欧美在线 | 久久国产乱子伦精品免 |