链表三连击
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í)了題解以后才明白的。
需要分三步完成重排:
我手?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é)
- 上一篇: 才装了固态,现在玩lol在回城之后会卡下
- 下一篇: D3力导引图