從頭遍歷到末尾,再次從頭遍歷到中間處。O(L+L/2) =O(3L/2)
利用快慢指針原理:設置兩個指針fast 和mid,都指向單鏈表的頭節點。其中fast的移動速度是mid的2倍。當fast指向末尾節點的時候,mid正好就在中間了。O(L/2)
public static int void getMidNode(MyList L){ MyList fast,mid; fast = L.head; mid = L.head; while(fast.next != null){ if(fast.next.next!=null){ fast = fast.next.next; mid = mid.next; } else fast = fast.next; } return mid.data;}利用快慢指針原理,最后快慢指針相撞。
1. 有環時求環的長度 記錄碰撞點P,slow、fast指針從該點出發,再次碰撞所走過的操作數就是環的長度s。 2. 找出環的連接點 有定理:碰撞點p到連接點的距離=頭指針到連接點的距離,因此,分別從頭結點,碰撞點開始走(相同的速度),相遇的地方就是連接點。 證明:
假設單鏈表的總長度為L,頭結點到環入口的距離為a,環入口到快慢指針相遇的結點距離為x,環的長度為r,慢指針總共走了s步,則快指針走了2s步。另外,快指針要追上慢指針的話快指針至少要在環里面轉了一圈多(假設轉了n圈加x的距離),得到以下關系:s = a + x;2s = a + nr + x;=>a + x = nr;=>a = nr - x;由上式可知:若在頭結點和相遇結點分別設一指針,同步(單步)前進,則最后一定相遇在環入口結點,搞定!附圖:
3. 求帶環鏈表的長度 問題2中已經求出連接點距離頭指針的長度,加上問題1中求出的環的長度,二者之和就是帶環單鏈表的長度


法1:假設第一條和第二條鏈表的長度為len1,len2,然后找出較長的鏈表,并讓其從|len1- len2|,開始遍歷,逐個比較兩個鏈表的值。 法2:將兩個鏈表壓棧,并比較兩個棧出來的數據,直到兩個數據不同時,就可以判斷相交點。
問題的延伸: 如果原來的兩個鏈表中有環怎么處理? a.創建第一個鏈表的地址hash,直到所有節點都存入(終結條件就是添加新的hash時,hash表中已經存在了)。遍歷第二個鏈表,并hash,判斷是否在表中。 b.分三種情況:兩條head都不在環上,都在環上,有一個在環上,這三種方式都可以用快慢指針進行判斷。 

|
新聞熱點
疑難解答