【優選算法】鏈表

在這里插入圖片描述

目錄

  • 鏈表常用的技巧和操作
    • 1、常用技巧
    • 2、常用操作
  • 一、[兩數相加](https://leetcode.cn/problems/add-two-numbers/description/)
  • 二、[兩兩交換鏈表中的節點](https://leetcode.cn/problems/swap-nodes-in-pairs/description/)
  • 三、[重排鏈表](https://leetcode.cn/problems/reorder-list/description/)
  • 四、[合并 K 個升序鏈表](https://leetcode.cn/problems/merge-k-sorted-lists/description/)
  • 五、[K 個一組翻轉鏈表](https://leetcode.cn/problems/reverse-nodes-in-k-group/description/)
  • 結尾

鏈表常用的技巧和操作

1、常用技巧

  1. 畫圖

  2. 引入虛擬頭結點

    • 便于我們處理邊界情況
    • 方便我們對鏈表進行操作
  3. 不要吝嗇空間,大膽定義變量
    相信我們在上學期間學習過數據結構的同學都很熟悉,給你兩個節點,使用雙向鏈接將其鏈接起來,但是只給你一個節點的地址,要求你在兩個節點之間插入一個新節點,大家可能都被鏈接的順序惡心過,但是只要定義一個變量記錄另一個節點的地址,那么我們想怎么鏈接就怎么鏈接了。

  4. 快慢雙指針

2、常用操作

  1. 創建一個新節點
  2. 頭插
  3. 尾插

一、兩數相加

題目描述
在這里插入圖片描述

思路講解
本道題只需要模擬兩數相加的過程即可,首先定義一個虛擬頭結點,這樣就不需要對鏈表進行特殊處理,然后定義兩個變量分別記錄對應位上兩數相加的個位和進位,創建一個節點存儲個位上的數字,尾插到虛擬頭結點所在的鏈表中,然后同時將兩個原始鏈表向后同時移動,重復上面的操作,直到兩個鏈表都遍歷完后返回以虛擬頭結點后面一個節點為頭結點的鏈表即完成本題。

需要注意兩數相加時還要加上進位,若是某個鏈表對應位上沒有節點,我們認定這個節點上的數字為0。

編寫代碼

/*** 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:ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {int add = 0;ListNode* newhead = new ListNode();ListNode* cur = newhead;while(l1 || l2 || add){int num1 = (l1 != nullptr) ? l1->val : 0;int num2 = (l2 != nullptr) ? l2->val : 0;int sum = num1 + num2 + add;ListNode* newNode = new ListNode(sum % 10);cur->next = newNode;cur = cur->next;add = sum / 10;if(l1 != nullptr)   l1 = l1->next;if(l2 != nullptr)   l2 = l2->next;}return newhead->next;}
};

二、兩兩交換鏈表中的節點

題目描述
在這里插入圖片描述

思路講解
本道題我們需要做的就是將鏈表中每兩個節點進行交互即可,我們只需要模擬如何將節點進行交換即可。若鏈表中只有一個節點時,不需要進行交換,返回即可。

這里我創建一個虛擬頭結點用來避免對鏈表第一次交換進行特殊處理,通過畫圖我們發現,看似是對兩個節點進行交換,實際上卻涉及到了四個節點,為了我們方便處理,直接定義四個指針分別指向四個連續的節點,有了這四個指針就可以很方便的將兩個節點進行交換了,如下圖,我們只需要修改prve、cur和next指向節點中next的指向即可,修改完指向后就需要指針向后移動了,各個指針移動后對應的位置在下圖中有明確的標識,有些指針移動后位置比較特殊,需要特殊判斷。

在這里插入圖片描述

然后就是循環的判斷條件了,這里我們將鏈表分類奇數節點個數和偶數節點個數來看,如圖,奇數情況下只要next沒有指向節點就結束,偶數情況下cur沒有指向節點就結束,綜上只要cur或next有一個沒有指向節點就結束循環。最后返回以虛擬頭結點后面一個節點為頭結點的鏈表即完成本題。
在這里插入圖片描述

編寫代碼

/*** 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:ListNode* swapPairs(ListNode* head) {if(head == nullptr || head ->next == nullptr)return head;ListNode* newhead = new ListNode();ListNode* prev = newhead ,*cur = head ;ListNode* next = head->next , *nnext = next->next;while(cur != nullptr && next != nullptr){prev->next = next;next->next = cur;cur->next = nnext;prev = cur;cur = nnext;if(cur)next = cur->next;if(next)nnext = next->next;}return newhead->next;}
};

三、重排鏈表

題目描述
在這里插入圖片描述

思路講解

本道題是讓我們將鏈表重新排序,并且不能只修改節點的值,而是要進行節點之間的切換,我們看了題目的示例,可以得出重排鏈表,實際上是重復拿出原鏈表中的頭節點和尾節點,并將尾節點鏈接到頭節點的后面,然后按照拿出來的順序進行鏈接,即可完成對鏈表的重排。

本題還有一個更簡單的思路,就是將這個鏈表從中間分開變為兩個鏈表,使前面鏈表的節點個數比后面的鏈接節點個數多一個或是相等,然后將后面這個鏈表逆轉,最后通過兩個鏈表的合并即可完成鏈表的重排。

編寫代碼

/*** 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->next == nullptr)return;ListNode* slow = head , *fast = head -> next;while(fast && fast->next){slow = slow->next;fast = fast->next->next;}// 從中間截斷為兩段鏈表ListNode* newhead1 = new ListNode();ListNode* cur = slow -> next;slow->next = nullptr;ListNode* next = cur->next;// 逆置后半段鏈表cur->next = nullptr;while(cur){cur->next = newhead1->next;newhead1 -> next = cur;cur = next;if(next)next = next -> next;}ListNode* cur1 = head ,*cur2 = newhead1->next;ListNode* next1 = head->next ,*next2 = cur2->next;ListNode* newhead2 = new ListNode();cur = newhead2;while(cur2){// 依次插入兩個鏈表cur -> next = cur1;cur1 = next1;if(next1)next1 = next1->next;cur = cur -> next;cur -> next = cur2;cur2 = next2;if(next2)next2 = next2->next;cur = cur -> next;}// 第一段鏈表一定與第二段鏈表等長或更長if(cur1)cur->next = cur1;head = newhead2;}
};

四、合并 K 個升序鏈表

題目描述
在這里插入圖片描述

思路講解
本道題是想讓我們將k個升序鏈表,按照節點的大小合并為1個升序鏈表,這里我們一定能想到的就是暴力解法,每次遍歷所以鏈表的頭節點,找到最小的節點并取出,再將這個節點鏈入到新鏈表中,重復這樣的操作,直到k個鏈表中沒有任何節點位置,最后返回新鏈表即可完成本道題,這樣完成本道題的時間復雜度為O(nk2^22)。

這里可以使用優先級隊列進行優化,我們創建一個小堆,將所有鏈表的頭節點放入小堆中,小堆根據節點的大小將最小的節點移動到堆頂,這樣我們就可以通過找到堆頂元素就可以找到k個鏈表中頭節點中最小的節點了,將該節點從堆中和它所對應的鏈表中取出,并將它所對應鏈表中的新頭節點放入到堆中,若沒有節點則不需加入,小堆則會按照它的特性將堆中的節點重新調整,然后將取出來的節點鏈接到新的鏈表中,重復這樣的操作直到堆中沒有任何節點為止,最后將新鏈表返回即可完成合并 K 個升序鏈表。

編寫代碼

/*** 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:ListNode* mergeKLists(vector<ListNode*>& lists) {int count = lists.size(); // 鏈表的個數ListNode* newhead = new ListNode();ListNode* last = newhead;// 記錄鏈表中有節點的鏈表個數int ListCount = 0;while(1){int MinPos = 0;int min = 10001;for(int i = 0 ; i < count; i++){ListNode* cur = lists[i];if(cur){   ListCount++;if(min > cur->val){min = cur->val;MinPos = i;}}}// 當鏈表所有鏈表都沒有節點時跳出循環if(ListCount == 0)break;last->next = lists[MinPos];// 插入到新的鏈表中last = last -> next;if(lists[MinPos])lists[MinPos] = lists[MinPos]->next;MinPos = 0 , ListCount = 0;}return newhead->next;}
};

五、K 個一組翻轉鏈表

題目描述
在這里插入圖片描述

思路講解
本道題想讓我們將鏈表中每k個節點進行翻轉,若剩下的節點小于k個則保持愿意。

這里可以使用模擬的思路解決本題,我們先遍歷整個鏈表,得到鏈表中節點的個數為num,有每k個節點需要翻轉一次,通過num/k得到有count組子鏈表需要翻轉。循環count次,每次記錄該組子鏈表的前一個節點和后一個節點,將本組k個節點進行逆序,再鏈接回原鏈表中,這里可以使用頭插法的方式將鏈表進行逆序,最后返回鏈表的頭結點即可。

編寫代碼

/*** 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:ListNode* reverseKGroup(ListNode* head, int k) {int numNode = 0;  // 節點個數ListNode* cur = head;while(cur){numNode++;cur = cur->next;}int opCount = numNode / k;  // 記錄需要翻轉的次數ListNode* newhead = new ListNode();   // 創建哨兵位頭結點newhead->next = head;ListNode* prev = newhead; // 標記每k個節點的前一個節點,方便鏈接cur = head;ListNode* connect = cur; // 旋轉k個節點后的最后一個節點,方便鏈接ListNode* next = cur->next; while(opCount--){connect = cur;for(int i = 1 ; i <= k ; i++){cur->next = prev->next;prev->next = cur;cur = next;if(next)next = next->next;}// 記錄前一段的尾prev = connect;}prev->next = cur;return newhead->next;}
};

結尾

如果有什么建議和疑問,或是有什么錯誤,大家可以在評論區中提出。
希望大家以后也能和我一起進步!!🌹🌹
如果這篇文章對你有用的話,希望大家給一個三連支持一下!!🌹🌹

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/90505.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/90505.shtml
英文地址,請注明出處:http://en.pswp.cn/web/90505.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

制造業新突破:AR 培訓系統助力復雜操作輕松上手?

在制造業&#xff0c;生產設備復雜、操作流程繁瑣&#xff0c;新員工掌握操作技能不易。比如汽車制造企業的發動機裝配環節&#xff0c;涉及眾多精密零部件安裝&#xff0c;對安裝順序、位置精度要求嚴格&#xff0c;一點小失誤都可能影響發動機性能甚至引發質量問題。過去新員…

《計算機網絡》實驗報告八 加密、數字簽名與證書

目 錄 1、實驗目的 2、實驗環境 3、實驗內容 3.1 對稱加密 3.2 散列函數 3.3 非對稱加密 3.4 數字簽名 3.5 證書 4、實驗結果與分析 4.1 對稱加密 4.2 散列函數 4.3 非對稱加密 4.4 數字簽名 4.5 證書 5、實驗小結 5.1 問題與解決辦法&#xff1a; 5.2 心得體…

MySQL(157)如何分析和優化存儲過程?

分析和優化存儲過程是數據庫性能優化的重要環節。通過對存儲過程進行分析和優化&#xff0c;可以提高數據庫操作的執行效率&#xff0c;減少資源消耗&#xff0c;改善系統整體性能。以下是詳細的步驟和代碼示例&#xff0c;介紹如何分析和優化 MySQL 存儲過程。 一、分析存儲過…

基于深度學習的胸部 X 光圖像肺炎分類系統(一)

本文先重點介紹了過采樣的原理是實現。 由于醫學數據相對缺乏&#xff0c;過采樣是解決數據問題的方法之一。 后續寫一篇搭建神經網絡的說明 目錄 概述 導入必要的庫 數據加載和預處理函數 處理樣本不均衡函數 構建改進的 CNN 模型函數 主函數 數據生成器generator&…

【PGCCC】在 Postgres 中構建復制安全的 LSM 樹

在原生 Postgres 實現中&#xff0c;全文搜索由B 樹或GIN&#xff08;廣義倒排索引&#xff09;結構支持。這些索引針對相對快速的查找進行了優化&#xff0c;但受限于 B 樹的寫入吞吐量。 當我們構建pg_searchPostgres 搜索和分析擴展時&#xff0c;我們的優先級有所不同。為了…

架構如鐘擺:在變與不變之間優雅平衡

在當今數字轉型浪潮中&#xff0c;企業在“快速創新”與“長期穩定”之間反復拉扯。是否應該重建所有架構以適應AI&#xff1f;又是否該死守傳統系統確保安全與合規&#xff1f;在The Open Group阿姆斯特丹峰會上&#xff0c;凱捷全球 CTO Ron Tolido 借用了一個極具畫面感的比…

LLM中的位置嵌入矩陣(Position Embedding Matrix)是什么

LLM中的位置嵌入矩陣(Position Embedding Matrix)是什么 在大語言模型(LLM)中,位置嵌入矩陣(Position Embedding Matrix) 是用來表示輸入序列中每個詞的位置信息的矩陣。它的核心作用是:讓模型能夠區分“相同詞在不同位置的語義差異”(比如“貓喜歡魚”中的“貓”和“…

國產DevOps平臺Gitee:如何重塑中國企業研發效能新格局

國產DevOps平臺Gitee&#xff1a;如何重塑中國企業研發效能新格局 在全球數字化轉型浪潮中&#xff0c;軟件研發效率已成為企業競爭力的核心指標。作為中國最大的代碼托管平臺&#xff0c;Gitee正通過其全棧式DevOps解決方案&#xff0c;助力中國企業突破研發效能瓶頸&#xff…

告別混亂!【Java Web】項目分層架構全指南:核心三層 + 關鍵輔助包詳解

目錄 1.前言 2.正文 2.1為什么要分層 2.2核心三層詳解 2.2.1Controller層&#xff08;表現層/API層&#xff09; 2.2.2Service層&#xff08;業務邏輯層&#xff09; 2.2.3DAO層&#xff08;持久層&#xff09; 2.3. 核心關系與數據流轉&#xff1a;分層架構的交互邏輯…

解決Docker Compose報錯

解決Docker Compose報錯&#xff1a;exec ./entrypoint.sh: no such file or directory在使用Docker Compose部署應用時&#xff0c;你是否遇到過exec ./entrypoint.sh: no such file or directory這個令人頭疼的錯誤&#xff1f;本文將深入分析錯誤原因并提供多種解決方案&…

【element plus】el-select,allow-create不需要點回車鍵

<el-selectv-model"row.expertName"filterableremoteallow-createdefault-first-optionreserve-keywordplaceholder"請輸入姓名":remote-method"remoteMethod":loading"loadingName"change"(val) > handleNameChange(row, …

RK3588 HDMI-RX 驅動、RGA 加速與 OpenCV GStreamer 支持完整指南

一、環境檢測與前置依賴 確認內核與 HDMI-RX 節點&#xff1a; uname -a # 輸出&#xff1a;6.1.0-1025-rockchip ...dmesg | grep -i hdmirx # 應能看到 hdmirx-controller 節點&#xff1a; # fdee0000.hdmirx-controller driver probe ok!如果僅出現&#xff1a; rockchi…

AS32A601芯片QSPI 調試技術解析與與實戰經驗分享

一、概述&#xff08;一&#xff09;QSPI 簡介QSPI&#xff08;Quad Serial Peripheral Interface&#xff09;是一種高速串行通信接口&#xff0c;在標準 SPI&#xff08;Serial Peripheral Interface&#xff09;的基礎上擴展至 4 條數據線&#xff08;Quad Mode&#xff09;…

TDengine 轉化函數 TO_TIMESTAMP 用戶手冊

TDengine TO_TIMESTAMP 函數用戶使用手冊 函數概述 TO_TIMESTAMP 是 TDengine 中的標量函數&#xff0c;用于將字符串按照指定格式轉換為時間戳。該函數在數據導入、時間格式轉換、以及處理各種時間字符串格式時非常有用。 語法 TO_TIMESTAMP(ts_str_literal, format_str_liter…

關于我司即將對商業間諜行為進行法律訴訟的通知

最后警告我司所屬社交媒體中所有友商間諜&#xff1a;請于2025年7月26日上午十點前&#xff0c;自行刪除我方好友&#xff0c;并停止通過欺詐行為&#xff08;包括但不限于冒充客戶等&#xff09;盜取我司商業秘密的行為。十點后&#xff0c;我司將開始進行逐一排查&#xff0c…

【打怪升級 - 03】YOLO11/YOLO12/YOLOv10/YOLOv8 完全指南:從理論到代碼實戰,新手入門必看教程

引言&#xff1a;為什么選擇 YOLO&#xff1f; 在目標檢測領域&#xff0c;YOLO&#xff08;You Only Look Once&#xff09;系列模型一直以其高效性和準確性備受關注。作為新版本&#xff0c;YOLO系列的新版本總能在前輩的基礎上進行了多項改進&#xff0c;包括更高的檢測精度…

JMeter每次壓測前清除全部以確保異常率準確(以黑馬點評為例、詳細圖解)

目錄 一、前言 二、未清除全部會出現的情況(以樂觀鎖解決超賣問題為例) 三、清除全部就能得到準確的結果 一、前言 在學習黑馬點評之前我并沒有接觸過JMeter這個壓測軟件&#xff0c;然后在黑馬點評視頻中老師也是直接拿起JMeter就開始使用&#xff0c;所以我一直在不斷搜索…

關于新學C++編程Visual Studio 2022開始,使用Cmake工具構建Opencv和SDK在VS里編譯項目開發簡介筆記

1. C 項目build文件夾 2. VS解決方案管理器Solution——.sln文件 3. CMake 自動化構建工具 4. SDK軟件開發工具包作為初學者&#xff0c;從工程項目開始接觸完整一套流程工具和編譯&#xff0c;有助于快速上手。 一、C 項目build文件夾在 VS2022 中打開 C 項目后&#xff0c;在…

測試ppyoloe的小樣本few-shot能力,10張圖片精度達到69.8%

近期公司有個項目&#xff0c;需要解決長尾樣本的問題&#xff0c;所以測試了一下paddlepaddle小樣本的能力。 環境&#xff1a;&#xff1a;T4 、ubuntu 、cuda-11.6 、py3.9、 paddlepaddle-gpu2.6.0、pip install opencv-python4.5.5.64 -i https://pypi.tuna.tsinghua.…

結構化布線系統詳解

1. 結構化布線系統概述 結構化布線系統(Structured Cabling System, SCS)是一種標準化、模塊化的建筑物或建筑群內信息傳輸基礎設施&#xff0c;它為語音、數據、圖像等多媒體業務提供了統一的物理傳輸介質。與傳統的點對點布線方式不同&#xff0c;結構化布線采用層次化、標準…