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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

链表三连击

發布時間:2023/11/30 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 链表三连击 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

876:鏈表的中間節點
206:反轉鏈表
143:重排練表

鏈表的中間節點

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

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

/*** 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;} };

看了一下題解的實現方法,更加的簡潔。我的這種雖然能夠解決問題,但是沒有考慮另一種判斷快指針是否到達結尾的方式:fast != nullptr && fast->next != nullptr。以后應該都考慮一下,然后按照最簡單的方式實現。

反轉鏈表

就是將一個鏈表進行反轉。

不知怎么的我把題目看成了反轉輸出,可能是因為ACM里面很少對原數據進行操作的原因。反轉輸出我想到的只有遞歸輸出。

有兩種方法,迭代法和遞歸法。迭代法很容易想到,也很容易實現。

在實現迭代法的時候我在想能不能使用C++中的二級指針簡化操作(因為一般刪除之類的使用二級指針都會方便許多),但是稍微思考一下發現,我們使用二級指針是為了解決無法原地修改指針的問題,但是這個是可以直接修改的(因為每一個節點都要進行修改),而且還必須需要保存前一個節點的信息,因此使用二級指針就完全是雞肋。

遞歸法我想的是重新寫一個函數,然后進行處理。但是看到題解中一個十分優美的實現方式,雖然效率不一定高(不一定比迭代法低)

/*** 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;} };

其中注釋部分為迭代法

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

重排鏈表

將鏈表從頭部挑一個,尾部挑一個,然后重復這個過程直到鏈表為空。

我自己完全沒有思路,是學習了題解以后才明白的。

需要分三步完成重排:

  • 找到鏈表的中點
  • 將中點后面的鏈表反轉
  • 將前后兩個鏈表合并
  • 我手擼了一下,因為才學習了上面兩個問題,所以代碼寫的很流暢,但是為了盡可能少命名變量可能看起來有些迷惑。

    /*** 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;// 求鏈表的中點ListNode *fast =head, *slow = head;while(fast->next != nullptr && fast->next->next != nullptr){fast = fast->next->next;slow = slow->next;}// 將鏈表的后半部分反轉fast = slow->next;ListNode *pre = nullptr, *next = nullptr;while(fast != nullptr){next = fast->next;fast->next = pre;pre = fast;fast = next;}fast = pre;//進行合并slow->next = nullptr;slow = head;while(fast != nullptr){next = slow->next;slow->next = fast;pre = fast->next;fast->next = next;slow = next;fast = pre;}} };

    總結

    以上是生活随笔為你收集整理的链表三连击的全部內容,希望文章能夠幫你解決所遇到的問題。

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