LeetCode 25 - K 個一組翻轉鏈表

LeetCode 25 - K 個一組翻轉鏈表

這道題是一個典型的鏈表操作題,考察我們對鏈表的精確操作,包括反轉鏈表、分組處理、遞歸和迭代的結合應用等。還可以通過變體問題延伸到優先隊列操作、歸并、分塊等,這使得它成為面試中的高頻考題之一。


題目描述

給你一個鏈表,每 k 個節點一組進行翻轉,并返回翻轉后的鏈表。

  • k 是一個正整數,它的值小于或等于鏈表的長度。
  • 如果節點總數不是 k 的整數倍,那么請將最后剩余節點保持原樣。
  • 你不允許更改節點的值,只能調整節點指針的方向。

示例

輸入:head = [1,2,3,4,5], k = 2
輸出:[2,1,4,3,5]輸入:head = [1,2,3,4,5], k = 3
輸出:[3,2,1,4,5]

解題思路與分析

核心簡化問題

  1. 分段處理鏈表:將鏈表分成每 k 個一組。
  2. 對每一組執行反轉操作。
  3. 當遍歷到不足 k 個節點的部分時,維持原順序不再反轉。
  4. 方法可以通過遞歸或迭代完成。

解法與代碼模板

解法 1:遞歸法

核心思路
  • 使用遞歸配合局部反轉:
    1. 確定鏈表是否有足夠的 k 個節點:如果不足 k 個,直接返回頭節點。
    2. 如果有足夠的 k 個節點:
      • 完成當前組內 k 個節點的反轉,
      • 遞歸地對剩余部分鏈表繼續處理。
    3. 將當前反轉的部分連接到下一組遞歸結果。
模板代碼
class Solution {public ListNode reverseKGroup(ListNode head, int k) {// 檢查鏈表是否有足夠的 k 個節點ListNode current = head;int count = 0;while (current != null && count < k) {current = current.next;count++;}// 如果不足 k 個節點,直接返回原鏈表if (count < k) {return head;}// 反轉當前 k 個節點ListNode prev = null, next = null;current = head;for (int i = 0; i < k; i++) {next = current.next;   // 暫存下一節點current.next = prev;  // 改變指針方向prev = current;       // 移動 prev 指針current = next;       // 移動 current 指針}// 遞歸處理剩余鏈表,并連接反轉后的部分head.next = reverseKGroup(current, k);// 返回反轉后的頭節點return prev;}
}
復雜度分析
  • 時間復雜度: O(N)
    • 每個節點僅訪問一次。
  • 空間復雜度: O(N / k)
    • 遞歸調用棧的深度為 (鏈表長度 / k)
優缺點
  • 優點:代碼簡潔并且邏輯清晰,適合遞歸思路的場景。
  • 缺點:會造成大量遞歸棧調用,鏈表很長時可能出現棧溢出。

解法 2:迭代法

核心思路
  • 相對于遞歸法,用 迭代 來實現分組反轉鏈表,避免了遞歸棧空間的開銷:
    1. 使用 啞結點dummy node)作為新鏈表的起始位置,方便連接。
    2. 遍歷鏈表,分別找到每一組的起始結點和結束結點。
    3. 將當前分組進行反轉,并連接到已經處理好的鏈表部分。
    4. 當剩余節點不足時,停止反轉,直接連接到尾部。
模板代碼
class Solution {public ListNode reverseKGroup(ListNode head, int k) {// 創建啞結點ListNode dummy = new ListNode(-1);dummy.next = head;ListNode prevGroupEnd = dummy;while (true) {// 找到當前組的開始和結束節點ListNode groupStart = prevGroupEnd.next;ListNode groupEnd = prevGroupEnd;for (int i = 0; i < k; i++) {groupEnd = groupEnd.next;if (groupEnd == null) {return dummy.next; // 不足 k 個節點}}// 下一組的起始節點ListNode nextGroupStart = groupEnd.next;// 反轉當前組reverseList(groupStart, groupEnd);// 連接反轉后的部分prevGroupEnd.next = groupEnd; // 當前組的結尾變成起始點groupStart.next = nextGroupStart;// 更新 prevGroupEnd 為這一組的最后節點prevGroupEnd = groupStart;}}private void reverseList(ListNode start, ListNode end) {ListNode prev = null, current = start, next = null;ListNode stop = end.next; // 保存停止位置while (current != stop) {next = current.next;current.next = prev;prev = current;current = next;}}
}
復雜度分析
  • 時間復雜度: O(N)
    • 每個節點最多被訪問兩次(反轉和連接)。
  • 空間復雜度: O(1)
    • 沒有額外棧空間的使用,僅需常數級別指針。
優缺點
  • 優點: 比遞歸方法更高效,適用于超長鏈表。
  • 缺點: 實現邏輯上稍微復雜。

解法 3:棧輔助法

核心思路
  • 借助棧來反轉每一組節點:
    1. 遍歷鏈表,將 k 個節點壓入棧中。
    2. 當棧中節點數量達到 k 時,出棧并重新連接節點指針。
    3. 如果節點數量不足 k,直接連接剩余部分。
模板代碼
import java.util.Stack;class Solution {public ListNode reverseKGroup(ListNode head, int k) {if (head == null || k <= 1) return head;Stack<ListNode> stack = new Stack<>();ListNode dummy = new ListNode(-1);ListNode prev = dummy;dummy.next = head;while (head != null) {// 將 k 個節點壓入棧for (int i = 0; i < k && head != null; i++) {stack.push(head);head = head.next;}// 判斷棧中是否有足夠的 k 個節點if (stack.size() == k) {// 出棧并重新連接while (!stack.isEmpty()) {prev.next = stack.pop();prev = prev.next;}prev.next = head; // 連接當前組與下一組}}return dummy.next;}
}
復雜度分析
  • 時間復雜度: O(N)
    • 每個節點入棧、出棧一次。
  • 空間復雜度: O(k)
    • 棧空間用于存儲每組 k 個節點。
優點和缺點
  • 優點: 實現簡單,不需要復雜鏈表反轉邏輯。
  • 缺點: 額外使用棧空間,適用于較短鏈表。

經典變體問題

變體 1:反轉鏈表 II

  • 反轉鏈表的第 m 到第 n 個節點(LeetCode 92)。
  • 解法類似,利用迭代進行指定區域反轉。

變體 2:K 個一組翻轉鏈表,但跳過一些組

  • 例如:對鏈表分組,但只翻轉奇數組或者僅反轉偶數組。

變體 3:分組排序

  • 例如:對鏈表的每組節點排序而不是反轉。

快速 AC 總結

  1. 遞歸與迭代優先掌握
    • 遞歸:邏輯清晰但容易出現棧溢出,適用于理論驗證。
    • 迭代:高效且空間復雜度較低,是面試中優選方法。
  2. 啞節點技巧
    • 在處理鏈表操作時,借助啞節點可以避免很多冗余的頭節點邊界條件處理。
  3. 多練變體問題
    • 如部分反轉、跳過反轉的場景,可以輕松遷移基礎模板。

通過對鏈表反轉操作的熟悉,配合經典模板化實現,可以快速應對鏈表轉化類問題,并高效解決工程中復雜數據結構操作場景。

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

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

相關文章

Leetcode 54: 螺旋矩陣

Leetcode 54: 螺旋矩陣 是一道經典的矩陣遍歷模擬題目&#xff0c;要求我們以螺旋順序遍歷一個二維數組。這個問題在面試中非常經典&#xff0c;考察模擬、數組操作以及邏輯清晰度。掌握本題的高效解法可以迅速給面試官留下好印象。 適合面試的解法&#xff1a;邊界法&#xff…

abseil-cpp:環境搭建

參考: https://abseil.io/docs/cpp/quickstart-cmake abseil-cpp.git/dd4c89b abseil-cpp.git/20240722.1 1. clone代碼倉庫、編譯 git clone https://github.com/abseil/abseil-cpp.git /app/abseil-cpp/ #/app/abseil-cpp/.git/config git checkout 20240722.1git rev-pa…

Storm實時流式計算系統(全解)——下

storm編程案例-網站訪問來源實時統計-需求 storm編程-網站訪問來源實時統計-代碼實現 根據以上條件可以只寫一個類&#xff0c;我們只需要寫2個方法和一個main&#xff08;&#xff09;&#xff0c;一個讀取/發射&#xff08;spout&#xff09;。 一個拿到數據統計后發到redis…

什么是SYN洪范攻擊?

文章目錄 一、什么是SYN洪范攻擊&#xff1f;二、SYN泛洪攻擊原理2.1 TCP 三次握手過程2.2 SYN攻擊過程 三、防御措施 一、什么是SYN洪范攻擊&#xff1f; SYN洪泛攻擊&#xff08;SYN Flood&#xff09;發生在OSI第四層&#xff0c;是一種基于?TCP協議三次握手漏洞?的DoS&a…

【嵌入式】MQTT

MQTT 文章目錄 MQTT安裝簡介MQTT客戶端代碼 安裝 安裝Paho MQTT C庫: sudo apt-get install libpaho-mqtt3-dev頭文件包含&#xff1a; #include "MQTTClient.h"編譯選項&#xff1a; gcc -o $ $^ -lpaho-mqtt3c簡介 MQTT協議全稱是&#xff08;Message Queuing…

ubuntu離線安裝nvidia-container-runtime

參考文章 ubuntu系統docker20.4版本安裝nvidia-container-runtime3.11.0-1版本(離線安裝nvidia-docker) - jokerMM - 博客園 https://zhuanlan.zhihu.com/p/15194336245 一、軟件地址 Index of /nvidia-docker/libnvidia-container/stable/ 從上述地地址——進入對應系統—…

用Python+Flask打造可視化武俠人物關系圖生成器:從零到一的實戰全記錄

用PythonFlask打造可視化武俠人物關系圖生成器&#xff1a;從零到一的實戰全記錄 一、緣起&#xff1a;一個程序小白的奇妙探索之旅 作為一個接觸Python僅13天的編程萌新&#xff0c;我曾以為開發一個完整的應用是遙不可及的事情。但在DeepSeek的幫助下&#xff0c;我竟用短短…

RPA 職業前景:個人職場發展的 “新機遇”

1. RPA職業定義與范疇 1.1 RPA核心概念 機器人流程自動化&#xff08;RPA&#xff09;是一種通過軟件機器人模擬人類操作&#xff0c;自動執行重復性、規則性任務的技術。RPA的核心在于其能夠高效、準確地處理大量數據和流程&#xff0c;減少人工干預&#xff0c;從而提高工作…

Full GC 排查

在 Java 中&#xff0c;Full GC&#xff08;完全垃圾回收&#xff09;會對整個堆&#xff08;包括年輕代和老年代&#xff0c;甚至可能包括永久代/元空間&#xff09;進行垃圾回收&#xff0c;通常會導致較長的停頓&#xff08;STW&#xff0c;Stop-The-World&#xff09;。如果…

go語言中字符串嵌套

在Go語言中&#xff0c;字符串嵌套通常是指在字符串中包含另一個字符串。可以通過以下幾種方式實現&#xff1a; 1. 使用雙引號和轉義字符 如果需要在字符串中嵌套雙引號&#xff0c;可以使用轉義字符 \ 來表示內部的雙引號。例如&#xff1a; s : "He said, \"He…

Docker 學習(二)——基于Registry、Harbor搭建私有倉庫

Docker倉庫是集中存儲和管理Docker鏡像的平臺&#xff0c;支持鏡像的上傳、下載、版本管理等功能。 一、Docker倉庫分類 1.公有倉庫 Docker Hub&#xff1a;官方默認公共倉庫&#xff0c;提供超過10萬鏡像&#xff0c;支持用戶上傳和管理鏡像。 第三方平臺&#xff1a;如阿里…

js的簡單介紹

一.javascript&#xff08;是什么&#xff09; 是一種運行在客戶端(瀏覽器)的編程語言&#xff0c;實現人機交互效果 作用 網頁特效&#xff08;監聽客戶的一些行為讓網頁做出對應的反饋&#xff09;表單驗證(針對表格數據的合法性進行判斷)數據交互(獲取后臺的數據&#xf…

k8s架構及服務詳解

目錄 1.1.容器是什么1.2.Namespace1.3.rootfs5.1.Service介紹5.1.1.Serice簡介 5.1.1.1什么是Service5.1.1.2.Service的創建5.1.1.3.檢測服務5.1.1.4.在運行的容器中遠程執行命令 5.2.連接集群外部的服務 5.2.1.介紹服務endpoint5.2.2.手動配置服務的endpoint5.2.3.為外部服務…

01. HarmonyOS應用開發實踐與技術解析

文章目錄 前言項目概述HarmonyOS應用架構項目結構Ability生命周期 ArkTS語言特性裝飾器狀態管理 UI組件與布局基礎組件響應式布局樣式與主題 頁面路由與參數傳遞頁面跳轉參數接收 數據綁定與循環渲染數據接口定義循環渲染 條件渲染組件生命周期最佳實踐與性能優化組件復用響應式…

【虛擬機 IP 配置深度剖析】

虛擬機 IP 配置深度剖析 在虛擬機的使用過程中&#xff0c;IP 配置猶如搭建房屋的基石&#xff0c;是確保虛擬機與外部網絡順暢通信、與其他設備高效交互的關鍵所在。本文將以 CentOS 虛擬機為例&#xff0c;深入解讀 IP 配置的奧秘。 一、認識網絡模式 ? NAT 模式&#xf…

【Python 數據結構 5.棧】

目錄 一、棧的基本概念 1.棧的概念 2.入棧 入棧的步驟 3.出棧 出棧的步驟 4.獲取棧頂元素 獲取棧頂元素的步驟 二、 Python中的棧 順序表實現 鏈表實現 三、棧的實戰 1.LCR 123. 圖書整理 I 思路與算法 2.LCR 027. 回文鏈表 思路與算法 3.1614. 括號的最大嵌套深度 思路與算法 …

Machine Learning 初探

前置知識 pandas 讀取文件&#xff1a;read_csv查看信息 describe&#xff1a;查看整體信息&#xff0c;包括每列的平均值、最大最小值、標準差等head&#xff1a;輸出頭部幾行數據columns&#xff1a;輸出所有列名loc&#xff1a;查詢數據&#xff0c;或是根據索引取對應的數…

2025年2月個人工作生活總結

本文為 2025年2月工作生活總結。 工作記錄 AI浪潮 AI非常火&#xff0c;春節至今&#xff0c;到處充斥著大量和AI、DeepSeek有關的新聞。領導也一再強調要用AI&#xff0c;甚至納入到新一年的考核里。再往上&#xff0c;大領導開會的新聞稿里也作出要求&#xff0c;不能停下腳…

SpringBoot @ConfigurationProperties 注解使用

ConfigurationProperties 用于將配置文件&#xff08;如 application.properties 或 application.yml&#xff09;中的屬性批量綁定到一個 Java Bean 中。 1. 定義配置文件 在 application.properties 或 application.yml 中定義一組具有相同前綴的屬性。 application.yml &a…

剛安裝docker并啟動docker服務: systemctl restart docker報錯解決

root:/home/lzw# sudo systemctl restart docker Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xeu docker.service" for details. 1、問題描述 啟動doc…