【數據結構】鏈表常見題目

文章目錄

  • 鏈表
    • 合并兩個有序鏈表
    • 反轉鏈表
    • 復制帶隨機指針的鏈表
    • 環形鏈表
    • 環形鏈表II
    • 相交鏈表
    • 移除鏈表元素
    • 鏈表中倒數第k個節點
    • 鏈表分割
    • 鏈表的回文結構
    • 鏈表的中間節點
    • 旋轉鏈表
    • 鏈表排序
    • 鏈表求和 (逆序求)
    • 鏈表求和II (正序求)
    • 重排鏈表
    • 奇偶鏈表
    • 反轉鏈表II <==> 鏈表內指定區間反轉
    • 刪除鏈表中的節點
    • 刪除有序鏈表當中重復的元素I
    • 刪除有序鏈表當中重復的元素II
    • 合并K個升序鏈表
    • K個一組反轉鏈表
    • 交換鏈表中的節點
    • 二進制鏈表轉整數
    • 鏈表隨機節點

鏈表

合并兩個有序鏈表

https://leetcode.cn/problems/merge-two-sorted-lists/

1.定義一個哨兵位節點和一個tail節點標志尾節點

2.遍歷兩條有序鏈表,誰小就鏈接誰

3.最后還剩一條鏈表是沒有遍歷完成的,那么就讓tail節點鏈接它

class Solution {
public:ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {//1.新建哨兵位節點ListNode* phead = new ListNode(-1);ListNode* tail = phead;//2.誰小就鏈接誰while(list1 && list2){if(list1->val > list2->val){tail->next = list2;tail = list2;list2 = list2->next;}else {tail->next = list1;tail = list1;list1 = list1->next;}}//3.判斷誰還沒有鏈接完if(list1) tail->next = list1;if(list2) tail->next = list2;return phead->next;}
};

反轉鏈表

https://leetcode.cn/problems/reverse-linked-list/description/

prev:記錄前一個節點 cur:當前遍歷到的節點 next:保存cur的下一個節點

  • 先保存下一個節點 然后更改cur的指向,指向前一個節點
  • 然后迭代往后走
class Solution {
public:ListNode* reverseList(ListNode* head) {ListNode* prev = nullptr;//記錄前一個節點ListNode* cur = head;//記錄當前節點ListNode* next = nullptr;//記錄下一個節點while(cur){next = cur->next;//先保存下一個節點cur->next = prev;//更改當前節點指向//prev cur next 迭代往后走prev = cur;cur = next;}return prev;}
};

復制帶隨機指針的鏈表

https://leetcode.cn/problems/copy-list-with-random-pointer/

1.在原鏈表節點之后拷貝一個節點

image-20230816094513759

2.處理拷貝節點的random指針

  • 注意:拷貝節點的random指針指向的節點是其原鏈表節點的random指針指向的節點的下一個節點
  • 坑點:有可能cur->random是空,也就是原來節點的random指針為空,那么當前拷貝節點的random指針也應該為空,否則cur->random->next 就會對空指針解引用!

image-20230816094637865

3.分離兩條鏈表

  • 最好定義一個哨兵位節點和一個tail指針用于標記鏈接拷貝鏈表,
  • cur CopyCur next三者的關系重新處理

image-20230816094751726

class Solution {public:Node* copyRandomList(Node* head) {if(head == nullptr ) return nullptr;//1.在原節點后面copy一個節點Node* cur = head;while(cur){Node* copy = new Node(cur->val);//拷貝節點Node* next = cur->next;//cur copy next 鏈接cur->next = copy;copy->next = next;cur = next;//繼續復制下一個節點}//2.處理拷貝節點的random指針cur = head;while(cur){Node* curCopy = cur->next;//cur的拷貝節點curCopy->random = cur->random == nullptr?nullptr:cur->random->next;cur = curCopy->next;}//3.拆離拷貝鏈表cur = head;Node* pnewHead = new Node(-1);//哨兵位Node* tail = pnewHead;while(cur){//cur copyCur next  Node* copyCur = cur->next;Node* next = copyCur->next;copyCur->next = nullptr;//讓拷貝節點獨立存在tail->next = copyCur;tail = tail->next;//重新處理鏈接關系,向后走cur->next = next;cur = next;}return pnewHead->next;}
};

環形鏈表

https://leetcode.cn/problems/linked-list-cycle/description/

方法:使用快慢指針,二者從頭開始走,一個一次走兩步,一個一次走一步,當二者相遇的時候,說明有環

class Solution {
public:bool hasCycle(ListNode *head) {//鏈表為空//注意:一個節點也能成環! 自己指向自己if(!head) return false;//快慢指針ListNode* fast = head;ListNode* slow = head;while(fast && fast->next){fast = fast->next->next;slow = slow->next;//二者相遇  注意:該條件不能放在上面!!!因為最初fast和slow都指向head,該條件應該放在下面if(slow == fast) return true;}return false;}
};

延申1:fast一次走兩步,slow一次走一步,為什么一定能相遇?會不會在環里錯過,永遠遇不上

結論:slow一次走一步,fast一次走兩步,如果存在環,slow和fast一定會在環內相遇

1.slow和fast,如果有環,一定是fast先進環,這時slow走了入環前距離的一半

2.隨著slow進環,fast已經在環里面走了一段距離了(距離的多少跟環的大小有關)

  • 假設slow進環的時候,slow和fast的距離為N,fast開始追趕slow

3.slow一次走一步,fast一次走兩步,二者的距離變化為:N N- 1 N -2 … 0,當二者的距離變為0的時候,就是相遇了

延申2:fast一次走n步(n>2),slow一次走一步,fast和slow能相遇嗎

結論:fast一次走n步(n>2),slow一次走一步,不一定會相遇

  • 假設有環,fast一次走n步,slow一次走1步,fast和slow的距離不斷減少n-1步

例子:假設fast一次走3步,如果slow進環之后,slow和fast的距離為N

如果N為偶數,那么二者之間的距離變化為:N N - 2 N - 4 … 2 0,此時二者相遇

如果N為計數,那么二者之間的距離變化為:N N - 2 N - 4 … 1 -1 ,二者距離變為-1,意味著fast超越了slow,此時fast和slow的距離為C -1 (假設C為環的大小)

  • 如果C - 1 為偶數,那么下一輪fast可以追上slow,二者相遇
  • 如果C - 1 為奇數,那么二者永遠追不上

環形鏈表II

https://leetcode.cn/problems/linked-list-cycle-ii/description/

做法:

1.先看是否有環,快慢指針,fast一次走兩步,slow一次走一步,如果存在環,fast和slow一定會相遇

2.假設相遇點為meetnode,一個指針從鏈表的頭開始走,一個指針從相遇點開始走,二者一次走一步,當二者相遇的時候,該位置就是入環節點

image-20230816102819793

class Solution {
public:ListNode *detectCycle(ListNode *head) {if(!head) return nullptr;//快慢指針ListNode* fast = head;ListNode* slow = head;while(fast && fast->next){fast = fast->next->next;slow = slow->next;//二者相遇  注意:該條件不能放在上面!!!因為最初fast和slow都指向head,該條件應該放在下面if(slow == fast) {//分別從相遇點和鏈表頭開始走,一次走一步  此時相遇就是入環位置ListNode* meet = slow;slow = head;while(slow != meet) {slow = slow->next;meet = meet->next;}return meet;}}return nullptr; //沒有環}
};

相交鏈表

https://leetcode.cn/problems/intersection-of-two-linked-lists/description/

方法1:將A鏈表的所有節點放到容器當中(要放地址,不能放值),然后遍歷B鏈表,看能否在容器當中找到該元素,如果找到,那么該節點就是相交節點

class Solution {
public://方法1:用容器保存其中一個鏈表的節點,然后遍歷另外一個鏈表進行比對ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {multiset<ListNode*> s;ListNode* cur = headA;while(cur) {s.insert(cur);cur = cur->next;}cur = headB;while(cur){cout << cur->val << endl;if(s.find(cur) != s.end()) return cur;cur = cur->next;}return nullptr;//不相交}
};

方法2:A中的每個結點和B分別比較(B和A比較也可以),看二者的地址是否一致 - O(N*M)

class Solution {
public:ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {ListNode* curA = headA;ListNode* curB = headB;while(curA) //確定一個A節點{curB = headB;while(curB)//遍歷整條B鏈表{if(curA == curB){return curA;}curB = curB ->next;}curA = curA->next;}return nullptr;}
};

方法3:

1.先統計兩條鏈表的長度,假設二者長度差距為gap

2.長鏈表先往后走gap步,然后長短鏈表一起往后走,如果相遇,那么就是相交節點

class Solution {public:ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {if(!headA || !headB) return nullptr;//1.統計兩條鏈表的長度int lenA = 0;int lenB = 0;ListNode* cur = headA;while(cur)  lenA++,cur = cur->next;cur = headB;

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

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

相關文章

(二)掌握最基本的Linux服務器用法——Linux下簡單的C/C++ 程序、項目編譯

1、靜態庫與動態庫 靜態庫(Static Library)&#xff1a;靜態庫是編譯后的庫文件&#xff0c;其中的代碼在編譯時被鏈接到程序中&#xff0c;因此它會與程序一起形成一個獨立的可執行文件。每個使用靜態庫的程序都會有自己的庫的副本&#xff0c;這可能會導致內存浪費。常用后綴…

opencv簡單使用

cv2庫安裝&#xff0c; conda install opencv-python注意cv2使用時&#xff0c;路徑不能有中文。&#xff08;不然會一直’None’ _ update # 處理中文路徑問題 def cv_imread(file_path): #使用之前需要導入numpy、cv2庫&#xff0c;file_path為包含中文的路徑return cv2.imd…

idea入門與maven配置的一些介紹

idea入門與maven配置的一些介紹 1.確保Java和Maven已安裝2.創建一個新的Maven項目3.導航到要創建項目的目錄配置Maven4.配置項目的pom.xml文件5.配置其他Tomcat和設置jdk6.構建和運行項目 關于idea入門基礎配置 步驟1&#xff1a;安裝IntelliJ IDEA 首先&#xff0c;從IntelliJ…

腳本語言與編譯語言的區別

文章目錄 一、語法差異二、執行方式差異三、應用領域差異四、總結 一、語法差異 腳本語言&#xff1a;腳本語言通常使用解釋器逐行執行&#xff0c;不需要事先編譯。它的語法相對簡單&#xff0c;易于學習和使用。常見的腳本語言有Python、JavaScript和Ruby等。 編譯語言&…

上海市青少年算法2023年2月月賽(丙組)

上海市青少年算法2023年2月月賽(丙組)T1 格式改寫 題目描述 給定一個僅由拉丁字符組成字符序列,需要改寫一些字符的大小寫,使得序列全部變成大寫或全部變成小寫,請統計最少修改多少個字符才能完成這項任務。 輸入格式 一個字符序列:保證僅由拉丁字符構成 輸出格式 單個整…

golang環境搭建

1. 下載、安裝 wget -O go.tar.gz https://golang.google.cn/dl/go1.21.0.linux-amd64.tar.gz sudo rm -rf /usr/local/go && sudo tar -zxvf go.tar.gz -C /usr/local2.創建工作目錄 cd mkdir -p go/{bin,pkg,src}3.添加環境變量 sudo vim /etc/profile寫入以下…

計算機競賽 python+大數據校園卡數據分析

0 前言 &#x1f525; 優質競賽項目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于yolov5的深度學習車牌識別系統實現 &#x1f947;學長這里給一個題目綜合評分(每項滿分5分) 難度系數&#xff1a;4分工作量&#xff1a;4分創新點&#xff1a;3分 該項目較為新穎&am…

記錄一個編譯TubeTK時的報錯:at_check問題

在使用如下命令安裝TubeTK的cuda_nms時&#xff0c;報了一個錯誤&#xff0c;記錄一下這個錯誤和解決辦法 (base) redmeryredmery:~/Desktop/MOT/TubeTK/post_processing/nms$ python setup.py build_ext --inplace因為這個命令是在/home/redmery/Desktop/MOT/TubeTK/install/…

Talk | ACL‘23 杰出論文獎上海交通大學吳蔚琪:預訓練語言模型對本體知識的記憶與理解

本期為TechBeat人工智能社區第523期線上Talk&#xff01; 北京時間8月17日(周四)20:00&#xff0c;上海交通大學碩士研究生—吳蔚琪的Talk已準時在TechBeat人工智能社區開播&#xff01; 她與大家分享的主題是: “預訓練語言模型對本體知識的記憶與理解”&#xff0c;分享了預訓…

Python入門【TCP建立連接的三次握手、 TCP斷開連接的四次揮手、套接字編程實戰、 TCP編程的實現、TCP雙向持續通信】(二十七)

&#x1f44f;作者簡介&#xff1a;大家好&#xff0c;我是愛敲代碼的小王&#xff0c;CSDN博客博主,Python小白 &#x1f4d5;系列專欄&#xff1a;python入門到實戰、Python爬蟲開發、Python辦公自動化、Python數據分析、Python前后端開發 &#x1f4e7;如果文章知識點有錯誤…

【c語言】通訊錄(動態版+文件+背景音樂)含源碼

開飯了&#xff0c;之前寫的通訊錄&#xff0c;是否會有人覺得申請1000人的空間是不是有點用不上呀&#xff0c;怎么才能做到要多少申請多少個呢&#xff1f;&#xff1f;我們學完動態內存管理&#xff0c;和文件的相關操作&#xff0c;終于可以繼續完善我們的通訊錄了 船新版本…

機器學習基礎(三)

邏輯回歸 場景 垃圾郵件分類 預測腫瘤是良性還是惡性 預測某人的信用是否良好 正確率與召回率 正確率與召回率(Precision & Recall)是廣泛應用于信息檢索和統計學分類領域的兩個度量值,用來評價結果的質量。 一般來說,正確率就是檢索出來的條目有多少是正確的,召回率就…

salesforce創建定時任務時明明implements the Schedulable interface卻提示不是的解決方法

Apex類&#xff1a; global class TimesheetWeeklyJob implements Schedulable{global void execute( SchedulableContext SC ) {WeeklyTimesheetProcess.markSubmitted();WeeklyTimesheetProcess.createNewSheets();} }卻提示&#xff1a; Error: You must select an Apex cl…

數據結構:二叉樹的遞歸實現(C實現)

個人主頁 &#xff1a; 個人主頁 個人專欄 &#xff1a; 《數據結構》 《C語言》 文章目錄 前言一、樹的概念二、二叉樹二叉樹的概念二叉樹的性質 三、二叉樹鏈式結構實現二叉樹節點定義創建二叉樹節點遍歷二叉樹先序遍歷二叉樹(BinaryTreePrevOrder)中序遍歷二叉樹(BinaryTree…

Air780EG —— 合宙4G定位解決方案

定位模式&#xff1a; 外部單片機控制模式(常見于AT固件客戶)&#xff1a; 開機 -> 搜星 -> 定位成功 -> 上報 -> 關機 780E自行控制模式(常見于二次開發客戶&#xff0c;AT用戶也可以使用): 開機 -> 搜星 -> 定位成功 -> 模塊休眠&#xff0c;關閉GP…

億發創新中醫藥信息化解決方案,自動化煎煮+調劑,打造智能中藥房

傳統中醫藥行業逐步復興&#xff0c;同時互聯網科技和人工智能等信息科技助力中醫藥行業逐步實現數字化轉型。利用互聯網、物聯網、大數據等科技&#xff0c;實現現代科學與傳統中醫藥的結合&#xff0c;提供智能配方顆粒調配系統、中藥自動化調劑系統、中藥煎配智能管理系統、…

【從零學習python 】40.python魔法方法(一)

文章目錄 魔法方法1. __init__ 方法2. __del__ 方法3. __str__ 方法4. __repr__ 方法5. __call__ 方法進階案例 魔法方法 Python 里有一種方法&#xff0c;叫做魔法方法。Python 的類里提供的&#xff0c;兩個下劃線開始&#xff0c;兩個下劃線結束的方法&#xff0c;就是魔法…

如何切換goland之中的版本號(升級go 到1.20)

go 安裝/版本切換_go 切換版本_云滿筆記的博客-CSDN博客 用brew就行&#xff1a; echo export PATH"/opt/homebrew/opt/go1.20/bin:$PATH" >> ~/.zshrc

[國產MCU]-BL602開發實例-OLED-SSD1306驅動與U8g2移植

OLED-SSD1306驅動與U8g2移植 文章目錄 OLED-SSD1306驅動與U8g2移植1、OLED介紹2、SSD1306介紹2、U8g2介紹3、U8g2移植3.1 定義U8g2圖形庫的移植函數3.2 移植函數實現3.3 移植函數調用4、驅動測試本文將詳細介紹如何在BL602中移植U8g2圖形庫,并通過U8g2庫驅動OLED SSD1306顯示屏…