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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

每天一道LeetCode-----逆序链表

發布時間:2024/4/19 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 每天一道LeetCode-----逆序链表 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Reverse Linked List

原題鏈接Reverse Linked List

逆序一個鏈表

首先是一個比較容易理解的方法,假設鏈表為A->B->C->D->E->F

通常在解決與鏈表有關的額問題時會預設置一個頭節點,

設置方法為

ListNode* header = new ListNode(-1); header->next = head; //head是鏈表的第一個節點

注:以下將head稱為鏈表的首節點,header稱為鏈表的頭節點

這種方法有以下幾個好處

  • 設置后鏈表的首節點(head)的前驅節點不再是nullptr,方便更改鏈表的首節點
  • 可用于解決鏈表首節點是空節點的情況
  • 可通過header->next作為最后的結果返回

不過第一種解決方法不需要將頭節點(header)的后驅節點設置為首節點(head),作為一般性情況,剛開始的結果鏈表是空,所以

header->next = nullptr;

獲得逆序鏈表的方法,依次遍歷原始鏈表,每遇到一個節點,就將其插入到header和header->next之間

以A->B->C->D->E->F鏈表為例

  • 初始時鏈表為header, nullptr
  • 遇到節點A時header, A, nullptr
  • 遇到節點B時header, B, A, nullptr
  • 遇到節點C時header, C, B, A, nullptr
  • 遇到節點F時header, F, E, D, C, B, A, nullptr

代碼比較容易

/*** 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* header = new ListNode(-1);ListNode* cur = head;while(cur){//將cur插入到header和header->next之間ListNode* next = cur->next;cur->next = header->next;header->next = cur;cur = next;}head = header->next;delete header;return head;} };

當然了,這種方法多少顯得有些笨拙,第二種方法看起來就有點,唔,高端

其實可以直接遍歷的時候逆序,而不是以插入為主要操作,所以最開始頭節點的后驅節點設置成首節點即可

header->next = head; //head是鏈表第一個節點

此時的鏈表大概是這個樣子

header->A->B->C->D->E->F->nullptr

逆序的思路是,一個一個逆序,即先逆序兩個,再逆序三個,…,直到逆序所有節點

逆序兩個,即逆序A->B

僅僅是交換位置嘛~額,換個角度看,實際上是將B提到header的后面,此時變為

header->B->A->C->D->E->F->nullptr

逆序三個,即逆序A->B->C

在上一步的基礎上,把C提到header的后面,此時變為

header->C->B->A->D->E->F->nullptr

啦啦啦~實際上就是依次將遍歷到的節點放在header的后面。其實就是小考慮一小部分,最后由部分到整體(算法思想叫啥來著?)

因為逆序后原鏈表的首節點(head)變為最后一個節點,所以實際上是將head的下一個節點提到header的后面(注意head->next一直在變)

代碼如下

/*** 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* header = new ListNode(-1);header->next = head;ListNode* cur = head;while(cur && cur->next){ListNode* next = cur->next;cur->next = next->next;//將next節點插入到header和header->next之間next->next = header->next;header->next = next;}head = header->next;delete header;return head;} };

Reverse Linked List II

原題鏈接Reverse Linked List II

仍然是逆序,但是只逆序第m個節點到第n個節點之間(包括m和n)的節點

所以說上面高端的做法這里就顯得比較簡潔,不過還是先用第一種方法試一下

首先找到第m-1個節點作為header,然后將遍歷到的節點依次插入到header和header->next之間

所以就存在兩種情況,一種是在[m, n]范圍內的節點,另一種不是

  • 如果節點在[m, n]范圍內,就將該節點插入到header和header->next之間
  • 如果節點不在[m, n]范圍內,就將節點追加到鏈表末尾

代碼如下

/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val(x), next(NULL) {}* };*/ class Solution { public:ListNode* reverseBetween(ListNode* head, int m, int n) {ListNode* header = new ListNode(-1);ListNode* cur = head;ListNode* prev = header;ListNode* reverseHeader = nullptr;int count = 1;while(cur){//在[m, n]之間,prev作為header,將遍歷到的節點插入到header和header->next之間//在這個過程中需要保存第m個節點,因為在離開[m, n]區域后,之前第m個節點需要作為prev的新值if(count >= m && count <= n){if(count == m)reverseHeader = cur;ListNode* next = cur->next;cur->next = prev->next;prev->next = cur;cur = next;if(count == n)prev = reverseHeader;}//追加到末尾,不要忘記將prev->next置為nullptrelse{prev->next = cur;prev = cur;cur = cur->next;prev->next = nullptr;}++count;}head = header->next;delete header;return head;} };

額,終于發現這種方法的不足了(只要從代碼長度看就不咋地)

應用第二種方法,原鏈表中直接逆序,但只需要逆序[m, n]范圍內的元素

那么,可以先找到第m個節點,逆序n-m次即可

/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val(x), next(NULL) {}* };*/ class Solution { public:ListNode* reverseBetween(ListNode* head, int m, int n) {ListNode* header = new ListNode(-1);header->next = head;n -= m;//prev是第m-1個節點ListNode* prev = header;while(--m)prev = prev->next;//cur是第m個節點ListNode* cur = prev->next;//n已經變為n-mwhile(n--){//prev是第m-1個節點,也是逆序節點集的header節點ListNode* next = cur->next;cur->next = next->next;next->next = prev->next;prev->next = next;}head = header->next;delete header;return head;} };

這兩道題主要是逆序鏈表問題,對于逆序節點可以依次將遇到的節點提到前面(方法二),這種方法比較高效,代碼也少:)

總結

以上是生活随笔為你收集整理的每天一道LeetCode-----逆序链表的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。