24_鏈表中環(huán)的入口節(jié)點(diǎn)

要求:給一個(gè)鏈表,若其中包含環(huán),請(qǐng)找出該鏈表的環(huán)的入口結(jié)點(diǎn),否則,輸出null。

思路:
1、第一步,確定一個(gè)鏈表中是否包含環(huán)。定義兩個(gè)指針,一個(gè)指針一次走一步,另一個(gè)指針一次走兩步,如果快指針追上慢指針,那么鏈表就包含環(huán)。
2、第二步,確定環(huán)中節(jié)點(diǎn)的數(shù)目。由于相遇節(jié)點(diǎn)一定在環(huán)中,然后從這個(gè)節(jié)點(diǎn)出發(fā),一邊繼續(xù)向前移動(dòng)一邊計(jì)數(shù),但再次回到這個(gè)節(jié)點(diǎn)的時(shí)候,就可以得到環(huán)中節(jié)點(diǎn)數(shù)了。
3、第三步,找到環(huán)中的入口節(jié)點(diǎn)。重新定義兩個(gè)指針A和B,初始都指向頭節(jié)點(diǎn),先讓A節(jié)點(diǎn)先移動(dòng)環(huán)中節(jié)點(diǎn)數(shù)目的步數(shù)。然后A和B再以相同速度移動(dòng),直到A和B相遇,相遇的節(jié)點(diǎn)就是環(huán)的入口節(jié)點(diǎn).

/*
 public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {
    public ListNode EntryNodeOfLoop(ListNode ListHead){
        if(ListHead == null){
            return null;
        }
        // 第一步,確定一個(gè)鏈表中包含環(huán),定義兩個(gè)指針,一個(gè)指針一次走一步,另一個(gè)指針一次走兩步,如果快指針追上慢指針,那么鏈表就包含環(huán)。
        ListNode slow = ListHead;
        ListNode fast = ListHead;
        boolean flag = false;
        // while退出循環(huán)條件:fast走兩步需要先判斷下一步后是否為空,因?yàn)榭罩羔槦o(wú)next
        // fast指針走向了末尾(null)都沒(méi)追上,說(shuō)明不包含環(huán)。
        while(fast.next!=null && fast != null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow){
                flag = true;
                break;
            }
        }
        if(!flag){
            return null;
        }else{
            // 第二步,確定環(huán)中節(jié)點(diǎn)的數(shù)目,由于相遇節(jié)點(diǎn)一定在環(huán)中,然后從這個(gè)節(jié)點(diǎn)出發(fā),一邊繼續(xù)向前移動(dòng)一邊計(jì)數(shù),但再次回到這個(gè)節(jié)點(diǎn)的時(shí)候,就可以得到環(huán)中節(jié)點(diǎn)數(shù)了。
            int n=1;   // n保留環(huán)內(nèi)的步數(shù)
            fast = fast.next;
            while(slow!=fast){
                n++;
                fast = fast.next;
            }
            // 此時(shí)獲取到環(huán)中的數(shù)目為n
            // 第三步,找到環(huán)中的入口節(jié)點(diǎn),重新定義兩個(gè)指針A和B,初始都指向頭節(jié)點(diǎn),先讓A節(jié)點(diǎn)先移動(dòng)環(huán)中節(jié)點(diǎn)數(shù)目的步數(shù)。然后A和B再以相同速度移動(dòng),直到A和B相遇,相遇的節(jié)點(diǎn)就是環(huán)的入口節(jié)點(diǎn).
            fast= ListHead;
            slow= ListHead;
            // fast先走n步
            for(int i=1; i<=n;i++){
                fast= fast.next;
            }
            // 再同時(shí)走,直到fast和slow相遇,此時(shí)為入口節(jié)點(diǎn),原理如23題
            while(fast != slow){
                fast = fast.next;
                slow = slow.next;
            }
            return slow;
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容