2022-10-15 算法訓(xùn)練第四天 (24 兩兩交換鏈表中的節(jié)點(diǎn),19 刪除鏈表中的倒數(shù)第N個(gè)節(jié)點(diǎn)诱桂, 面試題 02.07. 鏈表相交洋丐, 142.環(huán)形鏈表II )

24. 兩兩交換鏈表中的節(jié)點(diǎn)

解題思路:

題目的意思就是針對(duì)于一個(gè)鏈表,從頭結(jié)點(diǎn)開始挥等,每?jī)蓚€(gè)節(jié)點(diǎn)進(jìn)行交換友绝。
本題需要用到虛擬節(jié)點(diǎn)。
借助于一個(gè)while循環(huán)遍歷鏈表肝劲,循環(huán)的種植條件是當(dāng)前指針指向節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)不能為空且下下一個(gè)節(jié)點(diǎn)也不能是空迁客,這是因?yàn)楫?dāng)前指針指向的節(jié)點(diǎn)是已經(jīng)交換過的節(jié)點(diǎn),當(dāng)前節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)和下下一個(gè)節(jié)點(diǎn)都存在辞槐,那么還能交換掷漱,循環(huán)還能繼續(xù)。
但是如果沒有下一個(gè)節(jié)點(diǎn)榄檬,也就是當(dāng)前指針的next為空指針卜范,如果沒有下下一個(gè)節(jié)點(diǎn),那么當(dāng)前節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)的next為空鹿榜。這兩種情況都不需要再進(jìn)行交換海雪,循環(huán)自然要停止。
交換的具體思路是舱殿,首先針對(duì)于兩個(gè)要交換的節(jié)點(diǎn)奥裸,首先用tmp指針指向待交換的前節(jié)點(diǎn),tmp1指向后節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)沪袭,這樣就可以對(duì)后節(jié)點(diǎn)進(jìn)行操作了刺彩。
首先將待交換節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn)指向后節(jié)點(diǎn),后節(jié)點(diǎn)在指向前節(jié)點(diǎn),前節(jié)點(diǎn)在指向下一組的前節(jié)點(diǎn)创倔。最后將當(dāng)前節(jié)點(diǎn)移動(dòng)兩位嗡害,指向下一組待交換的節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn)。

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        ListNode* dummyHead = new ListNode(0);
        dummyHead->next = head;
        ListNode* cur = dummyHead;
        while(cur->next != nullptr && cur->next->next != nullptr) {
            ListNode* tmp = cur->next;
            ListNode* tmp1 = cur->next->next->next;

            cur->next = cur->next->next;
            cur->next->next = tmp;
            cur->next->next->next = tmp1;

            cur = cur->next->next;
        }
        return dummyHead->next;
    }
};

19. 刪除鏈表的倒數(shù)第 N 個(gè)結(jié)點(diǎn)

解題思路:

遇到刪除鏈表節(jié)點(diǎn)畦攘,就能使用虛擬節(jié)點(diǎn)霸妹,這樣方便操作。
題目中只給了倒數(shù)第幾個(gè)節(jié)點(diǎn)的信息知押√久可以借助于雙指針法,雙指針在本題中的作用是台盯,要?jiǎng)h除的節(jié)點(diǎn)相對(duì)尾節(jié)點(diǎn)指向的下一個(gè)空節(jié)點(diǎn)的位置罢绽,等于雙指針中前指針和后指針指向節(jié)點(diǎn)的相對(duì)位置。
首先借助于一個(gè)while循環(huán)静盅,循環(huán)的作用是指向刪除節(jié)點(diǎn)的指針向后挪動(dòng)一個(gè)位置良价,后指針就后挪一位。當(dāng)指向刪除節(jié)點(diǎn)的指針指向了空蒿叠,那么此時(shí)空節(jié)點(diǎn)的位置相對(duì)于待刪除節(jié)點(diǎn)的位置明垢,就和后指針與前指針的位置一樣了。
通過上述的相對(duì)位置市咽,就能借助于前后指針的相對(duì)位置判斷前指針是否已經(jīng)指向了待刪除節(jié)點(diǎn)痊银。但是由于刪除一個(gè)節(jié)點(diǎn)時(shí),需要當(dāng)前指針指向待刪除的節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn)施绎,所以就將后指針在往后挪移一位溯革,這樣當(dāng)后指針剛指向?yàn)榭眨爸羔槺阒赶蛄舜齽h除節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn)谷醉。后續(xù)就是借助于while循環(huán)致稀,同步挪動(dòng)兩個(gè)指針,當(dāng)后指針指向?yàn)榭諘r(shí)孤紧,停止挪動(dòng)豺裆。
然后借助于一個(gè)臨時(shí)指針,對(duì)待刪除節(jié)點(diǎn)進(jìn)行刪除操作号显。
最后返回虛擬頭節(jié)點(diǎn)中next指針臭猜。

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* dummyHead = new ListNode(0);
        dummyHead->next = head;
        ListNode* fast = dummyHead;
        ListNode* slow = dummyHead;

        while(n-- && fast != NULL) {
            fast = fast->next;
        }
        fast = fast->next;
        while(fast != NULL) {
            slow = slow->next;
            fast = fast->next;
        }
        ListNode* tmp = slow->next;
        slow->next = slow->next->next;
        delete tmp;
        return dummyHead->next;
    }
};

面試題 02.07. 鏈表相交

解題思路:

題目意思表達(dá)不是很明確,其實(shí)就是對(duì)于兩個(gè)鏈表押蚤,它們各有一個(gè)節(jié)點(diǎn)蔑歌,節(jié)點(diǎn)中的next指針是一樣的地址,這樣后續(xù)的節(jié)點(diǎn)就重合了揽碘,鏈表也就從下一個(gè)節(jié)點(diǎn)處開始相交次屠。
由于鏈表長(zhǎng)度不一园匹,所以需要讓兩個(gè)鏈表尾部對(duì)齊,開始遍歷的節(jié)點(diǎn)位置劫灶,也要對(duì)應(yīng)裸违。這一過程需要知道兩個(gè)鏈表的長(zhǎng)度,長(zhǎng)度通過移動(dòng)指針來確定本昏,由于不同情況下供汛,最長(zhǎng)的鏈表也不能確定,所以通過swap函數(shù)涌穆,讓最長(zhǎng)的長(zhǎng)度永遠(yuǎn)是sizea怔昨,通過sizea與sizeb做差,得到了較長(zhǎng)鏈表頭指針應(yīng)該挪動(dòng)的位數(shù)宿稀。
緊接著通過while循環(huán)趁舀,移動(dòng)兩個(gè)指針,當(dāng)存在兩個(gè)指針一致時(shí)祝沸,說明當(dāng)前指針指向的節(jié)點(diǎn)就是相交節(jié)點(diǎn)矮烹,返回該節(jié)點(diǎn),如果直到指針指向空奋隶,整個(gè)鏈表遍歷完畢擂送,都么有找到悦荒,說明不存在交點(diǎn)唯欣。于是跳出循環(huán),返回NULL搬味。

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode* cura = headA;
        ListNode* curb = headB;
        int sizea = 0;
        int sizeb = 0;
        
        while(cura != NULL) {
            sizea++;
            cura = cura->next;
        }
        while(curb != NULL) {
            sizeb++;
            curb = curb->next;
        }

        cura = headA;
        curb = headB;

        if(sizeb > sizea) {
            swap(sizea, sizeb);
            swap(cura, curb);
        }

        int gap = sizea - sizeb;

        while(gap--) {
            cura = cura->next;
        }

        while(curb != NULL) {
            if(cura == curb) {
                return cura;
            }
            cura = cura->next;
            curb = curb->next;
        }

        return NULL;
    }
};

142. 環(huán)形鏈表 II

解題思路:

這道題需要一點(diǎn)數(shù)學(xué)技巧境氢,本質(zhì)上就是一個(gè)追及問題,采用的方法為雙指針法碰纬。
如果一個(gè)鏈表中存在閉環(huán)萍聊,那么代表,不存在尾節(jié)點(diǎn)悦析,指針會(huì)一直遍歷下去寿桨,所以最外層是一個(gè)while循環(huán),當(dāng)快指針指向最后一個(gè)節(jié)點(diǎn)或者直接指向空時(shí)强戴,停止遍歷亭螟,這說明鏈表存在尾節(jié)點(diǎn),這時(shí)候跳出循環(huán)骑歹,返回NULL预烙。
如果存在閉環(huán)的話,由于快指針移動(dòng)速度要比慢指針移動(dòng)速度要快一步道媚,快指針會(huì)率先進(jìn)入閉環(huán)扁掸,且兩個(gè)指針一定會(huì)相遇翘县。當(dāng)兩個(gè)指針相遇的時(shí)候,借助于index1指針指向相遇節(jié)點(diǎn)谴分,index2指針指向了頭節(jié)點(diǎn)锈麸,然后移動(dòng)兩個(gè)指針,當(dāng)兩個(gè)指針相遇的時(shí)候牺蹄,指針指向的節(jié)點(diǎn)就是閉環(huán)的第一個(gè)節(jié)點(diǎn)掐隐。

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {

        ListNode* fast = head;
        ListNode* slow = head;

        while(fast != NULL && fast->next != NULL) {
            slow = slow->next;
            fast =fast->next->next;

            if(slow == fast) {
                ListNode* index1 = fast;
                ListNode* index2 = head;
                while(index1 != index2) {
                    index1 = index1->next;
                    index2 = index2->next;
                }
                return index2;
            }
        }

        return NULL;
    }
};
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市钞馁,隨后出現(xiàn)的幾起案子虑省,更是在濱河造成了極大的恐慌,老刑警劉巖僧凰,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件探颈,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡训措,警方通過查閱死者的電腦和手機(jī)伪节,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來绩鸣,“玉大人怀大,你說我怎么就攤上這事⊙轿牛” “怎么了化借?”我有些...
    開封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)捡多。 經(jīng)常有香客問我蓖康,道長(zhǎng),這世上最難降的妖魔是什么垒手? 我笑而不...
    開封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任蒜焊,我火速辦了婚禮,結(jié)果婚禮上科贬,老公的妹妹穿的比我還像新娘泳梆。我一直安慰自己,他們只是感情好榜掌,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開白布优妙。 她就那樣靜靜地躺著,像睡著了一般唐责。 火紅的嫁衣襯著肌膚如雪鳞溉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天鼠哥,我揣著相機(jī)與錄音熟菲,去河邊找鬼看政。 笑死,一個(gè)胖子當(dāng)著我的面吹牛抄罕,可吹牛的內(nèi)容都是我干的允蚣。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼呆贿,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼嚷兔!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起做入,我...
    開封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤冒晰,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后竟块,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體壶运,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年浪秘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蒋情。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡耸携,死狀恐怖棵癣,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情夺衍,我是刑警寧澤狈谊,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站刷后,受9級(jí)特大地震影響的畴,放射性物質(zhì)發(fā)生泄漏渊抄。R本人自食惡果不足惜尝胆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望护桦。 院中可真熱鬧含衔,春花似錦、人聲如沸二庵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽催享。三九已至杭隙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間因妙,已是汗流浹背痰憎。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工票髓, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人铣耘。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓洽沟,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親蜗细。 傳聞我的和親對(duì)象是個(gè)殘疾皇子裆操,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容