算法題目總結-鏈表

文章目錄

    • 1.環形鏈表
        • 1.答案
        • 2.思路
    • 2.兩數相加
        • 1.答案
        • 2.結果
    • 3.反轉鏈表
        • 1.答案
        • 2.思路
    • 4.反轉鏈表 II
        • 1.答案
        • 2.思路
    • 5.K 個一組翻轉鏈表
        • 1.答案
        • 2.思路
    • 6.刪除鏈表的倒數第 N 個結點
        • 1.答案
        • 2.思路
    • 7.刪除排序鏈表中的重復元素 II
        • 1.答案
        • 2.思路
    • 8.旋轉鏈表
        • 1.答案
        • 2.思路
    • 9.LRU 緩存
        • 1.答案
        • 2.思路
    • 10.兩兩交換鏈表中的節點
        • 1.答案
        • 2.思路
    • 11.環形鏈表 II
        • 1.答案
        • 2.思路

1.環形鏈表

1.答案
package com.sunxiansheng.arithmetic.day11;import com.sunxiansheng.arithmetic.util.ListNode;/*** Description: 141. 環形鏈表** @Author sun* @Create 2025/1/16 10:36* @Version 1.0*/
public class t141 {public boolean hasCycle(ListNode head) {// 快慢指針ListNode slow = head;ListNode fast = head;while (fast != null && fast.next != null) {slow = slow.next;fast = fast.next.next;// 只要相遇了,就是有環if (slow == fast) {return true;}}return false;}
}
2.思路

快慢指針,只要相遇,就有環

2.兩數相加

1.答案
package com.sunxiansheng.arithmetic.day11;import com.sunxiansheng.arithmetic.util.ListNode;/*** Description: 2. 兩數相加** @Author sun* @Create 2025/1/16 10:39* @Version 1.0*/
public class t2 {public ListNode addTwoNumbers(ListNode l1, ListNode l2) {// 結果的頭節點ListNode res = new ListNode(-1);ListNode cur = res;// 進位int carry = 0;// 遍歷兩個鏈表的指針ListNode t1 = l1, t2 = l2;// 只要兩個鏈表有一個不為空就進行遍歷while (t1 != null || t2 != null) {// 獲取兩個節點的值int var1 = t1 == null ? 0 : t1.val;int var2 = t2 == null ? 0 : t2.val;// 求和int sum = var1 + var2 + carry;// 用完進位之后要恢復0carry = 0;// 判斷是否要進位if (sum > 9) {carry = sum / 10;sum = sum % 10;}// 給結果賦值cur.next = new ListNode(sum);cur = cur.next;// 移動指針if (t1 != null) {t1 = t1.next;}if (t2 != null) {t2 = t2.next;}}// 檢查是否還有沒處理的進位if (carry > 0) {cur.next = new ListNode(carry);}return res.next;}
}
2.結果

核心是有一個進位的字段,多注意即可

3.反轉鏈表

1.答案
package com.sunxiansheng.arithmetic.day12;import com.sunxiansheng.arithmetic.util.ListNode;/*** Description: 206. 反轉鏈表** @Author sun* @Create 2025/1/17 09:56* @Version 1.0*/
public class t206 {public ListNode reverseList(ListNode head) {if (head == null) {return null;}// 哨兵節點ListNode dummy = new ListNode(0);dummy.next = head;// prevListNode prev = dummy;// startListNode start = head;// thenListNode then = start.next;while (start.next != null) {start.next = then.next;then.next = prev.next;prev.next = then;then = start.next;}return dummy.next;}
}
2.思路

首先需要有prev、start、then,然后只要start.next不為空,就進行反轉

4.反轉鏈表 II

1.答案
package com.sunxiansheng.arithmetic.day12;import com.sunxiansheng.arithmetic.util.ListNode;/*** Description: 92. 反轉鏈表 II** @Author sun* @Create 2025/1/17 09:52* @Version 1.0*/
public class t92 {public ListNode reverseBetween(ListNode head, int left, int right) {// 找到prev、start、then// 哨兵節點ListNode dummy = new ListNode(0);dummy.next = head;// 讓cur指向left的前一個節點作為prevListNode cur = dummy;for (int i = 0; i < left - 1; i++) {cur = cur.next;}ListNode prev = cur;ListNode start = cur.next;ListNode then = start.next;// 遍歷次數int count = right - left;for (int i = 0; i < count; i++) {start.next = then.next;then.next = prev.next;prev.next = then;then = start.next;}return dummy.next;}
}
2.思路

找到prev、start、then,然后遍歷次數為right - left

5.K 個一組翻轉鏈表

1.答案
package com.sunxiansheng.arithmetic.day12;import com.sunxiansheng.arithmetic.util.ListNode;/*** Description: 25. K 個一組翻轉鏈表** @Author sun* @Create 2025/1/17 10:21* @Version 1.0*/
public class t25 {public ListNode reverseKGroup(ListNode head, int k) {// 哨兵節點ListNode dummy = new ListNode(0);dummy.next = head;ListNode cur = dummy;// 提前記錄prevListNode prev = dummy;// 循環翻轉while (true) {// 先判斷有沒有一組for (int i = 0; i < k; i++) {cur = cur.next;// 只要發現沒有一組了,就返回結果if (cur == null) {return dummy.next;}}// 到這里就說明有一組,可以翻轉鏈表ListNode start = prev.next;ListNode then = start.next;reverseGroup(prev, start, then, k);// 更新prevprev = start;// 更新curcur = prev;}}/*** 翻轉一組鏈表** @param prev* @param start* @param then* @param k*/private void reverseGroup(ListNode prev, ListNode start, ListNode then, int k) {// 翻轉次數int count = k - 1;for (int i = 0; i < count; i++) {start.next = then.next;then.next = prev.next;prev.next = then;then = start.next;}}
}
2.思路

就是先判斷剩下的元素夠不夠k個,如果夠就進行反轉,翻轉之后要更新prev和cur

6.刪除鏈表的倒數第 N 個結點

1.答案
package com.sunxiansheng.arithmetic.day12;import com.sunxiansheng.arithmetic.util.ListNode;/*** Description: 19. 刪除鏈表的倒數第 N 個結點** @Author sun* @Create 2025/1/17 10:44* @Version 1.0*/
public class t19 {public ListNode removeNthFromEnd(ListNode head, int n) {// 哨兵節點ListNode dummy = new ListNode(0);dummy.next = head;ListNode cur = dummy;// 求出一共有多少個節點int count = 0;while (cur.next != null) {cur = cur.next;count++;}// 倒數第n個節點的前一個節點的索引int index = count - n;cur = dummy;while (index > 0) {cur = cur.next;index--;}// 目前cur指向了前一個節點,可以開始刪除節點了cur.next = cur.next.next;return dummy.next;}
}
2.思路

就是先找到一共有多少個節點,再找到倒數第n個節點的前一個節點然后刪除

7.刪除排序鏈表中的重復元素 II

1.答案
package com.sunxiansheng.arithmetic.day13;import com.sunxiansheng.arithmetic.util.ListNode;/*** Description: 82. 刪除排序鏈表中的重復元素 II** @Author sun* @Create 2025/1/19 09:32* @Version 1.0*/
public class t82 {public static ListNode deleteDuplicates(ListNode head) {// 哨兵節點ListNode dummy = new ListNode(300);dummy.next = head;ListNode cur = dummy;// 記錄前一個位置ListNode pre = dummy;while (cur.next != null) {cur = cur.next;if (cur.next == null || cur.val != cur.next.val) {pre = cur;} else {// 到這就說明pre的后兩個元素相同// 記錄一下值int val = cur.val;while (cur.next != null && val == cur.next.val) {cur = cur.next;}pre.next = cur.next;cur = pre;}}return dummy.next;}public static void main(String[] args) {ListNode head = new ListNode(1);head.next = new ListNode(1);head.next.next = new ListNode(1);head.next.next.next = new ListNode(2);head.next.next.next.next = new ListNode(3);deleteDuplicates(head);}
}
2.思路

就是有一個pre來記錄前一個位置,每次循環都讓cur先走一步,然后判斷當前元素跟下一個元素是不是相同,如果不相同或者目前是最后一個元素,就讓pre也指向cur,如果說當前元素跟下一個元素是相同的,那么就刪除相同元素,最終讓cur指向pre

8.旋轉鏈表

1.答案
package com.sunxiansheng.arithmetic.day13;import com.sunxiansheng.arithmetic.util.ListNode;import java.util.List;/*** Description: 61. 旋轉鏈表** @Author sun* @Create 2025/1/19 10:29* @Version 1.0*/
public class t61 {public ListNode rotateRight(ListNode head, int k) {if (head == null || head.next == null) {return head;}// 哨兵節點ListNode dummy = new ListNode(0);dummy.next = head;ListNode cur = dummy;// 計算鏈表總長度int length = 0;while (cur.next != null) {cur = cur.next;length++;}// 如果余數為0,則直接返回if (k % length == 0) {return head;}// 記錄鏈表末尾元素ListNode end = cur;// 移動到正數第length - k % length個位置int index = length - k % length;cur = dummy;while (index > 0) {cur = cur.next;index--;}dummy.next = cur.next;// 切斷,否則會有環cur.next = null;end.next = head;return dummy.next;}
}
2.思路

首先計算鏈表的總長度,然后記錄鏈表末尾元素,再通過計算,找到正數第length - k % length個位置,然后根據題意進行組裝,不過要注意切斷一下,否則會有環

9.LRU 緩存

1.答案
package com.sunxiansheng.arithmetic.day13;import java.util.HashMap;
import java.util.Map;/*** Description: 146. LRU 緩存** @Author sun* @Create 2025/1/19 10:55* @Version 1.0*/
public class LRUCache {// 雙向鏈表的節點class DLinkedNode {int key;int value;DLinkedNode prev;DLinkedNode next;public DLinkedNode() {}public DLinkedNode(int key, int value) {this.key = key;this.value = value;}}// 雙向鏈表的頭尾指針DLinkedNode head, tail;// map:key是key,value是雙向鏈表的節點private Map<Integer, DLinkedNode> map;// 容量private int capacity;public LRUCache(int capacity) {map = new HashMap<>();this.capacity = capacity;// 頭結點和尾節點head = new DLinkedNode();tail = new DLinkedNode();head.next = tail;tail.prev = head;}// 獲取元素public int get(int key) {// 從map中去獲取keyDLinkedNode dLinkedNode = map.get(key);if (dLinkedNode == null) {return -1;}// 獲取之后,將元素放到鏈表頭部moveToHead(dLinkedNode);return dLinkedNode.value;}private void moveToHead(DLinkedNode dLinkedNode) {// 首先需要在鏈表中刪除這個元素delete(dLinkedNode);// 然后將元素插入到頭部insertToHead(dLinkedNode);}private void insertToHead(DLinkedNode dLinkedNode) {dLinkedNode.next = head.next;dLinkedNode.prev = head;head.next.prev = dLinkedNode;head.next = dLinkedNode;}private static void delete(DLinkedNode dLinkedNode) {dLinkedNode.prev.next = dLinkedNode.next;dLinkedNode.next.prev = dLinkedNode.prev;}// 插入或更新元素public void put(int key, int value) {// 先獲取元素DLinkedNode dLinkedNode = map.get(key);// 如果元素有值了,就替換值,并移動到頭部if (dLinkedNode != null) {dLinkedNode.value = value;moveToHead(dLinkedNode);} else {// 沒有值則需要新增元素dLinkedNode = new DLinkedNode(key, value);// 確保容量足夠ensureCapacity(map.size() + 1);// 目前容量一定足夠,直接插入到頭部即可map.put(key, dLinkedNode);insertToHead(dLinkedNode);}}private void ensureCapacity(int newSize) {if (newSize <= capacity) {return;}// 如果容量不夠,則需要刪除最后的一個元素map.remove(tail.prev.key);delete(tail.prev);}
}
2.思路

使用雙向鏈表+map來做

首先需要一個雙向鏈表的類,key,value,next,prev即為屬性

然后需要三個參數,雙向鏈表的前后指針,map,容量

10.兩兩交換鏈表中的節點

1.答案
package com.sunxiansheng.arithmetic.day13;import com.sunxiansheng.arithmetic.util.ListNode;/*** Description: 24. 兩兩交換鏈表中的節點** @Author sun* @Create 2025/1/19 12:01* @Version 1.0*/
public class t24 {public ListNode swapPairs(ListNode head) {ListNode dummy = new ListNode(0);dummy.next = head;ListNode cur = dummy;// 提前記錄prevListNode prev = dummy;// 循環翻轉while (true) {// 先判斷是否有一組for (int i = 0; i < 2; i++) {if (cur.next == null) {return dummy.next;}cur = cur.next;}// 到這里就是有一組了,開始翻轉ListNode start = prev.next;ListNode then = start.next;reverse(prev, start, then);// 更新prev和curprev = start;cur = prev;}}// 兩個一組翻轉鏈表private void reverse(ListNode prev, ListNode start, ListNode then) {start.next = then.next;then.next = prev.next;prev.next = then;then = start.next;}
}
2.思路

就是兩個一組翻轉鏈表,翻轉鏈表的次數是節點數減一,然后要提前記錄prev,并且在翻轉后更新prev和start

11.環形鏈表 II

1.答案
package com.sunxiansheng.arithmetic.day13;import com.sunxiansheng.arithmetic.util.ListNode;/*** Description: 142. 環形鏈表 II** @Author sun* @Create 2025/1/19 12:31* @Version 1.0*/
public class t142 {public ListNode detectCycle(ListNode head) {// 快慢指針ListNode slow = head;ListNode fast = head;while (fast != null && fast.next != null) {slow = slow.next;fast = fast.next.next;if (slow == fast) {// 這樣只能代表有環,如果想要找到入環的第一個節點,就要讓slow等于head,然后一起移動slow = head;while (slow != fast) {slow = slow.next;fast = fast.next;}return slow;}}return null;}
}
2.思路

發現有環之后,如果想要找到入環的第一個節點,就要讓slow等于head,然后一起移動,直到相遇

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

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

相關文章

【Unity3D】3D物體擺放、場景優化案例Demo

目錄 PlaceManager.cs(放置管理類) Ground.cs(地板類) 和 GroundData.cs(地板數據類) 額外知識點說明 1、MeshFilter和MeshRenderer的Bounds區別 2、Gizmos 繪制一個平行于斜面的立方體 通過網盤分享的文件&#xff1a;PlaceGameDemo2.unitypackage 鏈接: https://pan.baid…

OpenEuler學習感悟

在初次接觸 OpenEuler 時&#xff0c;我深感其學習難度較大。它與我之前熟悉的操作系統存在諸多差異&#xff0c;學習過程中&#xff0c;需要理解復雜的內核機制、掌握獨特的系統配置方法。但正是這種挑戰&#xff0c;激發了我深入探索的熱情。 從理論學習入手&#xff0c;我發…

C# OpenCvSharp 部署文檔矯正,包括文檔扭曲/模糊/陰影等情況

目錄 說明 效果 模型 項目 代碼 下載 參考 C# OpenCvSharp 部署文檔矯正&#xff0c;包括文檔扭曲/模糊/陰影等情況 說明 地址&#xff1a;https://github.com/RapidAI/RapidUnDistort 修正文檔扭曲/模糊/陰影等情況&#xff0c;使用onnx模型簡單輕量部署&#xff0c…

CSS 溢出問題及解決方案:實用案例與技巧

在網頁開發中&#xff0c;CSS 的布局和樣式起著至關重要的作用&#xff0c;但經常會遇到一個棘手的問題——溢出問題。溢出是指元素內的內容超出了其設定的容器大小&#xff0c;這不僅會影響頁面的美觀&#xff0c;還可能干擾用戶體驗。本文將詳細探討 CSS 溢出問題的案例&…

生成樹機制實驗

1 實驗內容 1、基于已有代碼,實現生成樹運行機制,對于給定拓撲(four_node_ring.py),計算輸出相應狀態下的生成樹拓撲 2、構造一個不少于7個節點,冗余鏈路不少于2條的拓撲,節點和端口的命名規則可參考four_node_ring.py,使用stp程序計算輸出生成樹拓撲 2 實驗原理 一、…

數據結構詳解——堆與二叉樹

? 目錄 樹的概念樹的表示方法二叉樹的概念特殊的二叉樹二叉樹的性質二叉樹的存儲結構順序存儲鏈式存儲 堆的概念與結構堆的性質堆的實現堆的初始化入堆堆的擴容向上調整算法出堆&#xff08;最頂端元素&#xff09;向下調整算法 二叉樹的實現二叉樹的創建二叉樹的銷毀二叉樹的…

【藍橋杯】43694.正則問題

題目描述 考慮一種簡單的正則表達式&#xff1a; 只由 x ( ) | 組成的正則表達式。 小明想求出這個正則表達式能接受的最長字符串的長度。 例如 ((xx|xxx)x|(x|xx))xx 能接受的最長字符串是&#xff1a; xxxxxx&#xff0c;長度是 6。 輸入描述 一個由 x()| 組成的正則表達式。…

mac m1下載maven安裝并配置環境變量

下載地址&#xff1a;Download Apache Maven – Maven 解壓到一個沒有中文和空格的文件夾 輸入pwd查看安裝路徑 輸入cd返回根目錄再輸入 code .zshrc 若顯示 command not found: code你可以通過以下步驟來安裝和配置 code 命令&#xff1a; 1. 確保你已經安裝了 Visual Studio…

【自己動手開發Webpack插件:開啟前端構建工具的個性化定制之旅】

在前端開發的世界里&#xff0c;Webpack無疑是構建工具中的“明星”。它強大的功能可以幫助我們高效地打包和管理前端資源。然而&#xff0c;有時候默認的Webpack功能可能無法完全滿足我們的特定需求&#xff0c;這時候就需要自定義Webpack插件來大展身手啦&#xff01;今天&am…

移遠通信多模衛星通信模組BG95-S5獲得Skylo網絡認證,進一步拓展全球衛星物聯網市場

近日&#xff0c;全球領先的物聯網整體解決方案供應商移遠通信正式宣布&#xff0c;其支持“衛星蜂窩”多模式的高集成度NTN衛星通信模組BG95-S5已成功獲得NTN網絡運營商Skylo的網絡認證。BG95-S5也成為了獲得該認證的最新款移遠衛星通信模組。 BG95-S5模組順利獲得Skylo認證&a…

1.3.淺層神經網絡

目錄 1.3.淺層神經網絡 1.3.1 淺層神經網絡表示 1.3.2 單個樣本的向量化表示 1.3.4 激活函數的選擇 1.3.5 修改激活函數 1.3.5 練習??????? 1.3.淺層神經網絡 1.3.1 淺層神經網絡表示 之前已經說過神經網絡的結構了&#xff0c;在這不重復敘述。假設我們有如下…

StarRocks強大的實時數據分析

代碼倉庫&#xff1a;https://github.com/StarRocks/starrocks?tabreadme-ov-file StarRocks | A High-Performance Analytical Database 快速開始&#xff1a;StarRocks | StarRocks StarRocks 是一款高性能分析型數據倉庫&#xff0c;使用向量化、MPP 架構、CBO、智能物化…

2024年博客之星主題創作|貓頭虎分享AI技術洞察:2025年AI發展趨勢前瞻與展望

2025年AI發展趨勢前瞻&#xff1a;貓頭虎深度解析未來科技與商業機遇 摘要 2024年&#xff0c;AI技術迎來爆發式增長&#xff0c;AIGC、智能體、AIRPA、AI搜索、推理模型等技術不斷突破&#xff0c;AI應用場景持續擴展。2025年&#xff0c;AI將進入全新發展階段&#xff0c;W…

PG vs MySQL mvcc機制實現的異同

MVCC實現方法比較 MySQL 寫新數據時&#xff0c;把舊數據寫入回滾段中&#xff0c;其他人讀數據時&#xff0c;從回滾段中把舊的數據讀出來 PostgreSQL 寫新數據時&#xff0c;舊數據不刪除&#xff0c;直接插入新數據。 MVCC實現的原理 PG的MVCC實現原理 定義多版本的數據…

Android SystemUI——CarSystemBar視圖解析(十一)

前面文章我們已經把 CarSystemBar 從啟動到構建視圖,再到將視圖添加到 Window 的流程分析完畢,我們知道默認情況下在車載系統中只顯示頂部欄和底部欄視圖的。這里我們在前面文章的基礎上以頂部欄為例具體解析其視圖的結構。 一、頂部欄解析 通過《CarSystemBar車載狀態欄》這…

51c~ONNX~合集1

我自己的原文哦~ https://blog.51cto.com/whaosoft/11608027 一、使用Pytorch進行簡單的自定義圖像分類 ~ONNX 推理 圖像分類是計算機視覺中的一項基本任務&#xff0c;涉及訓練模型將圖像分類為預定義類別。本文中&#xff0c;我們將探討如何使用 PyTorch 構建一個簡單的自定…

每打開一個chrome頁面都會【自動打開F12開發者模式】,原因是 使用HBuilderX會影響谷歌瀏覽器的瀏覽模式

打開 HBuilderX&#xff0c;點擊 運行 -> 運行到瀏覽器 -> 設置web服務器 -> 添加chrome瀏覽器安裝路徑 chrome谷歌瀏覽器插件 B站視頻下載助手插件&#xff1a; 參考地址&#xff1a;Chrome插件 - B站下載助手&#xff08;輕松下載bilibili嗶哩嗶哩視頻&#xff09…

go語言之OOP特性和演示

一、OOP特性 Go語言中的OOP特性 結構體&#xff1a;在Go中&#xff0c;結構體用于定義復合類型&#xff0c;類似于其他語言中的類。它可以包含字段&#xff08;屬性&#xff09;和方法&#xff08;行為&#xff09;。方法&#xff1a;Go允許為任何自定義類型&#xff08;包括…

USB3020任意波形發生器4路16位同步模擬量輸出卡1MS/s頻率 阿爾泰科技

信息社會的發展&#xff0c;在很大程度上取決于信息與信號處理技術的先進性。數字信號處理技術的出現改變了信息 與信號處理技術的整個面貌&#xff0c;而數據采集作為數字信號處理的必不可少的前期工作在整個數字系統中起到關鍵 性、乃至決定性的作用&#xff0c;其應用已經深…

ChatGPT大模型極簡應用開發-目錄

引言 要理解 ChatGPT&#xff0c;了解其背后的 Transformer 架構和 GPT 技術一路的演進則變得非常必要。 ChatGPT 背后的 LLM 技術使普通人能夠通過自然語言完成過去只能由程序員通過編程語言實現的任務&#xff0c;這是一場巨大的變革。然而&#xff0c;人類通常容易高估技術…