日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

链表三连击

發(fā)布時(shí)間:2023/11/30 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 链表三连击 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

876:鏈表的中間節(jié)點(diǎn)
206:反轉(zhuǎn)鏈表
143:重排練表

鏈表的中間節(jié)點(diǎn)

這個(gè)題一看就是最簡(jiǎn)單的快慢指針,但是在具體實(shí)現(xiàn)的時(shí)候我還是猶豫思考了一下:要不要在鏈表前面放置啞節(jié)點(diǎn),快指針應(yīng)該什么時(shí)候判斷已經(jīng)到達(dá)結(jié)尾。但是單純的想并沒(méi)有什么結(jié)果。對(duì)于這種不是算法本身的問(wèn)題,而只是實(shí)現(xiàn)細(xì)節(jié)的問(wèn)題,不要多想,沒(méi)有很大的意義,只要對(duì)于每種情況都動(dòng)手(腦)模擬一遍,看這么樣能夠讓情形變得更加簡(jiǎn)單即可。

我思考了一下以后寫了一下自己的代碼:

/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val(x), next(NULL) {}* };*/ class Solution { public:ListNode* middleNode(ListNode* head) {ListNode *fast = head, *slow = head;while(fast->next != nullptr && fast->next->next !=nullptr){fast = fast->next->next;slow = slow->next;}if(fast->next == nullptr) return slow;else return slow->next;} };

看了一下題解的實(shí)現(xiàn)方法,更加的簡(jiǎn)潔。我的這種雖然能夠解決問(wèn)題,但是沒(méi)有考慮另一種判斷快指針是否到達(dá)結(jié)尾的方式:fast != nullptr && fast->next != nullptr。以后應(yīng)該都考慮一下,然后按照最簡(jiǎn)單的方式實(shí)現(xiàn)。

反轉(zhuǎn)鏈表

就是將一個(gè)鏈表進(jìn)行反轉(zhuǎn)。

不知怎么的我把題目看成了反轉(zhuǎn)輸出,可能是因?yàn)锳CM里面很少對(duì)原數(shù)據(jù)進(jìn)行操作的原因。反轉(zhuǎn)輸出我想到的只有遞歸輸出。

有兩種方法,迭代法和遞歸法。迭代法很容易想到,也很容易實(shí)現(xiàn)。

在實(shí)現(xiàn)迭代法的時(shí)候我在想能不能使用C++中的二級(jí)指針簡(jiǎn)化操作(因?yàn)橐话銊h除之類的使用二級(jí)指針都會(huì)方便許多),但是稍微思考一下發(fā)現(xiàn),我們使用二級(jí)指針是為了解決無(wú)法原地修改指針的問(wèn)題,但是這個(gè)是可以直接修改的(因?yàn)槊恳粋€(gè)節(jié)點(diǎn)都要進(jìn)行修改),而且還必須需要保存前一個(gè)節(jié)點(diǎn)的信息,因此使用二級(jí)指針就完全是雞肋。

遞歸法我想的是重新寫一個(gè)函數(shù),然后進(jìn)行處理。但是看到題解中一個(gè)十分優(yōu)美的實(shí)現(xiàn)方式,雖然效率不一定高(不一定比迭代法低)

/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val(x), next(NULL) {}* };*/ class Solution { public:ListNode* reverseList(ListNode* head) {/*ListNode* pre = nullptr, *cur = head, *next = nullptr;while(cur != nullptr){next = cur->next;cur->next = pre;pre = cur;cur = next;}return pre;*/if(head == nullptr || head->next == nullptr){return head;}ListNode *tail = reverseList(head->next);head->next->next = head;head->next = nullptr;return tail;} };

其中注釋部分為迭代法

遞歸法中比較難理解的就是返回的那個(gè)指針是什么,其實(shí)這個(gè)指針是鏈表的尾部,也就是新鏈表的頭部。

重排鏈表

將鏈表從頭部挑一個(gè),尾部挑一個(gè),然后重復(fù)這個(gè)過(guò)程直到鏈表為空。

我自己完全沒(méi)有思路,是學(xué)習(xí)了題解以后才明白的。

需要分三步完成重排:

  • 找到鏈表的中點(diǎn)
  • 將中點(diǎn)后面的鏈表反轉(zhuǎn)
  • 將前后兩個(gè)鏈表合并
  • 我手?jǐn)]了一下,因?yàn)椴艑W(xué)習(xí)了上面兩個(gè)問(wèn)題,所以代碼寫的很流暢,但是為了盡可能少命名變量可能看起來(lái)有些迷惑。

    /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/ class Solution { public:void reorderList(ListNode* head) {if(head == nullptr) return;// 求鏈表的中點(diǎn)ListNode *fast =head, *slow = head;while(fast->next != nullptr && fast->next->next != nullptr){fast = fast->next->next;slow = slow->next;}// 將鏈表的后半部分反轉(zhuǎn)fast = slow->next;ListNode *pre = nullptr, *next = nullptr;while(fast != nullptr){next = fast->next;fast->next = pre;pre = fast;fast = next;}fast = pre;//進(jìn)行合并slow->next = nullptr;slow = head;while(fast != nullptr){next = slow->next;slow->next = fast;pre = fast->next;fast->next = next;slow = next;fast = pre;}} };

    總結(jié)

    以上是生活随笔為你收集整理的链表三连击的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。