LeetCode算法題 (移除鏈表元素)Day15!!!C/C++

https://leetcode.cn/problems/remove-linked-list-elements/description/

一、題目分析

????????給你一個鏈表的頭節點?head?和一個整數?val?,請你刪除鏈表中所有滿足?Node.val == val?的節點,并返回?新的頭節點?。

? ? ? ? 今天的題目非常好理解,也就是要刪除掉鏈表中==val的值,并返回新的頭節點。

二、相關知識了解

? ? ? ? 鏈表這種數據結構其實與數組相似,同屬線性表,但是與數組相比的話,鏈表是不支持隨機訪問元素的,也就是說要想在鏈表中查詢一個元素的位置的話,時間復雜度最壞為O(n)如果要查找的元素位于鏈表末尾(或不存在),需要遍歷整個鏈表,遍歷次數為n次。)。平均也就是O((n + 1)/ 2)(這里就不過多的推導了,感興趣的同學可以期待一下下一期的題目,我會詳細帶著大家一起設計出一個功能相對完善的鏈表

對比數組的隨機訪問

  • 數組支持隨機訪問(通過下標),查詢時間為?O(1),這是鏈表與數組的核心差異之一。

  • 但鏈表在插入/刪除節點(尤其頭部)時更高效 O(1),而數組可能需要移動元素(O(n))。

三、示例分析

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

示例 2:

輸入:head = [], val = 1
輸出:[]

示例 3:

輸入:head = [7,7,7,7], val = 7
輸出:[]

四、解題思路&代碼實現

? ? ? ? 方法一:原鏈表刪除元素(復雜度為O(n))

? ? ? ? ? ?首先,拿到一個鏈表第一步我們要進行的是判斷該鏈表是否為空,如果為空的話直接return head就好。其次就是判斷當前節點的值是否==val。如果==的話那么就需要對該節點進行刪除操作。下面看一下具體代碼的實現。

class Solution {
public:ListNode* removeElements(ListNode* head, int val) {// 處理頭節點等于val的情況(可能需要連續刪除多個頭節點 如示例3)while (head && head->val == val) {ListNode* temp = head;  // 臨時保存當前頭節點head = head->next;      // 頭節點指向下一個節點delete temp;           // 釋放原頭節點的內存}// 遍歷鏈表,刪除非頭節點中值等于val的節點ListNode* cur = head;       // 當前節點指針while (cur && cur->next) {  // 當前節點和下一個節點均非空時循環if (cur->next->val == val) {// 如果下一個節點值等于val,則刪除它ListNode* temp = cur->next;  // 臨時保存待刪除節點cur->next = cur->next->next;  // 跳過待刪除節點,直接連接下下個節點delete temp;                  // 釋放待刪除節點的內存} else {// 否則,移動到下一個節點繼續檢查cur = cur->next;}}return head;  // 返回處理后的鏈表頭節點}
};

? ? ? ? 這里需要注意幾個關鍵點:

  1. 首先在C/C++中堆區開辟的空間需進行手動釋放,以免造成空間浪費,或者該空間內的臟數據影響程序結果。(一定要養成良好的編程習慣)
  2. 在第二個while語句終止條件中,一定要cur和cur->next都不為空時我們再去進行循環體,確保不會訪問到空指針。最終返回的head節點有可能為NULL,也就是示例3的情況。
  3. 在進行頭節點的處理使用while處理連續多個頭節點值等于?val?的情況而不是if(if只能處理一次(例如?[1,1,1,2]?刪除?1)。每次刪除節點時記得更新head節點,并使用delete釋放內存
  4. 如果?cur->next?的值等于?val,則修改?cur->next?跳過該節點,并釋放內存。如果不等,則正常移動到下一個節點。

????????方法二:虛擬頭節點法(復雜度為O(n))

? ? ? ? ? 虛擬頭節點法屬于是對法一進行的一個優化操作,可以顯著簡化鏈表操作,尤其是在處理涉及頭節點刪除或修改的問題時。

? ? ? ? 對比法一的優點:

  1. 無需特殊處理頭節點,虛擬頭節點始終作為鏈表的“前置節點”,使得真正的頭節點(dummy->next)和其他節點的刪除邏輯完全一致,避免分支判斷。
  2. 簡化代碼的結構,法一需要進行兩步操作,需先對頭節點進行預處理操作,再去處理其余節點。而使用虛擬頭節點則只需要一個循環即可處理所有節點,避免代碼冗余從而簡化代碼。
  3. 虛擬頭節點確保?cur?初始指向一個非空節點(dummy),因此?cur->next?的訪問總是安全的(無需額外判空)。

? ? ? ? 具體實現代碼如下:

class Solution {
public:ListNode* removeElements(ListNode* head, int val) {// 創建虛擬頭節點(dummy node),其值任意(這里設為0),next指向原鏈表頭節點// 使用虛擬頭節點可以統一處理原頭節點和其他節點的刪除邏輯ListNode* dummy = new ListNode(0);dummy->next = head;  // 將虛擬頭節點連接到原鏈表// cur指針用于遍歷鏈表,初始指向虛擬頭節點ListNode* cur = dummy;// 遍歷鏈表,檢查每個節點的下一個節點(cur->next)while (cur->next) {if (cur->next->val == val) {  // 如果下一個節點的值等于目標值ListNode* temp = cur->next;  // 臨時保存要刪除的節點cur->next = cur->next->next; // 跳過要刪除的節點,直接連接下下個節點delete temp;                 // 釋放要刪除節點的內存(避免內存泄漏)// 注意:這里不移動cur指針,因為新的cur->next可能也需要刪除// 例如鏈表[1,2,2,3],刪除2時需要連續檢查} else {cur = cur->next;  // 如果不需要刪除,則正常移動到下一個節點}}// 返回處理后的鏈表頭節點(即dummy->next)// 注意:原頭節點可能已被刪除,dummy->next會自動更新為新的頭節點ListNode* newHead = dummy->next;delete dummy;  // 釋放虛擬頭節點的內存return newHead;}
};

????????關鍵點說明:

  1. 虛擬頭節點:創建一個虛擬頭節點作為原鏈表的起始點,其next指針指向的為原鏈表的head節點?(作用:統一處理邏輯,避免單獨進行頭節點刪除操作)
  2. 返回值:這里需要注意我們需要返回的值應為虛擬頭節點的next,若原鏈表所有節點都已被刪除,那么虛擬頭節點的next會變為NULL,則無需處理。

????????其余與方法一相同!

至此算法已經是最優解!完結撒花!!!🌸🌸🌸

四、題目總結? ? ?

方法一:原鏈表刪除元素

此方法先對頭節點進行處理,若頭節點的值等于?val,則連續刪除頭節點直至其值不等于?val。之后遍歷鏈表,對非頭節點中值等于?val?的節點進行刪除操作。該方法時間復雜度為?O(n),不過在處理頭節點時需要額外的邏輯判斷,且要分別處理頭節點和非頭節點的刪除情況,代碼相對復雜。

方法二:虛擬頭節點法

這種方法創建了一個虛擬頭節點,將其?next?指針指向原鏈表的頭節點。通過遍歷鏈表,檢查每個節點的下一個節點,若其值等于?val?則進行刪除。此方法的優點在于統一了頭節點和其他節點的刪除邏輯,避免了額外的分支判斷,簡化了代碼結構。時間復雜度同樣為?O(n),是對方法一的優化。

總結

在處理鏈表刪除操作時,使用虛擬頭節點能有效簡化代碼,避免因頭節點的特殊情況而增加的復雜邏輯,提高代碼的可讀性和可維護性。兩種方法的時間復雜度均為線性,已達到最優解。在實際編程中,要養成手動釋放堆區內存的習慣,防止內存泄漏。今天的題解分享到這里,謝謝大家!!!荊軻刺秦!!!

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

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

相關文章

Scrapy框架之【Scrapy-Redis】分布式爬蟲詳解

Scrapy-Redis 介紹 Scrapy-Redis 是一個基于 Redis 實現的 Scrapy 分布式爬蟲組件。Scrapy 本身是一個強大的 Python爬蟲框架,但它默認是單進程單線程的,在面對大規模數據抓取任務時效率不高。Scrapy-Redis 則解決了這一問題,它允許你將 Scra…

Gradio全解20——Streaming:流式傳輸的多媒體應用(3)——實時語音識別技術

Gradio全解20——Streaming:流式傳輸的多媒體應用(3)——實時語音識別技術 本篇摘要20. Streaming:流式傳輸的多媒體應用20.3 實時語音識別技術20.3.1 環境準備和開發步驟1. 環境準備2. ASR應用開發步驟(基于Transform…

使用xlwings將兩張順序錯亂的表格進行數據核對

有如下一個excel表,姓名列的內容相同,順序不同;月薪有部分內容不同。 目的:要找出哪幾條月薪不同。 通常的做法,要使用excel的高級篩選。 在此,使用xlwings實現,在不同的內容上涂色。 代碼如…

2025大模型安全研究十大框架合集(10份)

2025大模型安全研究十大框架合集的詳細介紹: Anthropic AI信任研究框架 Anthropic于2024年10月更新的《安全責任擴展政策》(RSP),提出了一個靈活的動態AI風險治理框架。該框架規定當AI模型達到特定能力時,將自動升級安全措施,如…

Qt/C++開發監控GB28181系統/云臺控制/獲取預置位信息/添加刪除調用預置位

一、前言 之前用onvif已經完美實現了設備的云臺控制和預置位的功能,這個基礎功能在監控系統中是使用頻率很高的,所有gb28181肯定也提供了這樣的功能,很多人以為是通過包含xml數據,對應節點指定對應的動作來實現,其實不…

第T8周:貓狗識別

● 語言環境:Python3.8.8 ● 編譯器:Jupyter Lab ● 深度學習環境:TensorFlow2.4.1 貓狗識別 一、前期工作1. 設置GPU 二、數據預處理1. 加載數據2.再次檢查數據3.配置數據集 三、構建VG-16網絡四、編譯五、訓練模型六、模型評估七、預測八、…

主流微前端框架比較

主流微前端框架比較 以下表格列出了當前主流微前端框架的核心對比信息,包括基本介紹、核心特性、適用場景、技術棧兼容性、優缺點、社區維護情況和典型應用案例等: 框架基本介紹核心特性與機制適用場景技術棧兼容性優缺點社區維護情況典型應用案例qiankun螞蟻金服推出的生產…

大學生入學審核系統設計與實現【基于SpringBoot + Vue 前后端分離技術】

一、項目概述 1.1 項目背景 隨著高校的不斷擴招,傳統的入學審核管理模式已不能滿足大規模學生數據的處理需求。人工管理不僅效率低下,還容易出現疏漏。本系統通過信息化手段,提升入學審核過程中的數據管理和審批效率。 1.2 系統目標 系統…

云計算-容器云-服務網格Bookinfo

服務網格:創建 Ingress Gateway 將 Bookinfo 應用部署到 default 命名空間下,請為 Bookinfo 應用創建一個網 關,使外部可以訪問 Bookinfo 應用。 上傳ServiceMesh.tar.gz包 [rootk8s-master-node1 ~]# tar -zxvf ServiceMesh.tar.gz [rootk…

Spring 分批處理 + 冷熱數據分離:歷史訂單高效遷移與數據清理實戰

在實際業務中,隨著時間推移,訂單量持續增長,若未及時進行數據治理,會造成數據庫膨脹、查詢緩慢、性能下降等問題。為了實現數據分層管理和系統高性能運行,我們在項目中采用了“冷熱數據分離 分批遷移 數據清理”的綜…

新手SEO優化核心步驟

內容概要 對于SEO新手而言,建立系統化的優化框架是突破入門瓶頸的關鍵。SEO的核心在于通過技術手段與內容策略的結合,提升網站在搜索引擎中的可見性與用戶價值。具體而言,新手需優先掌握關鍵詞研究,明確目標用戶的搜索意圖&#…

C++ 之 【list的簡介、list 的構造函數、iterator、容量操作、元素訪問、增刪查改與迭代器失效】

目錄 1.list的介紹 2.list的使用 2.1 構造函數 2.2 iterator 的使用 2.3 容量操作 2.4 元素訪問 2.5 增刪查改 2.5.1頭插頭刪與尾插尾刪 2.5.2 insert 、erase 函數 2.5.3 clear、swap函數 2.5.4 關于find函數 3.迭代器失效 1.list的介紹 (1)list的底層通常實現為帶…

Laravel Octane 項目加速與靜態資源優化指南

Laravel Octane 項目加速與靜態資源優化指南 一、Octane 核心加速配置 擴展安裝與環境配置 composer require laravel/octane # 安裝核心擴展?php artisan octane:install # 生成配置文件(選擇 Swoole/RoadRunner 等服務器)?服務器參數調優? …

高露潔牙膏是哪個國家的品牌?高露潔牙膏哪一款最好?

高露潔是來自于美國一個比較有知名度的品牌,在1806年的時候創立。總部是在美國紐約公園大道,在1873年時,高露潔就已經開始銷售罐裝牙膏。 在1896年時期推出可折疊管牙膏,在口腔護理產品發展的過程中擁有著不容忽視的地位。在1992…

【Python爬蟲詳解】第八篇:突破反爬體系的工程實踐

當矛與盾的較量進入白熱化,突破反爬需要的不只是技巧,更是一套完整的工程化解決方案——本文將揭示對抗現代反爬體系的九大核心戰術。 一、JavaScript混淆的深度破解 1. AST(抽象語法樹)解混淆 案例:某電商平臺商品價…

【Linux調整FTP端口】

Linux調整FTP端口 一、確保新端口未被占用在修改端口之前,可以使用以下命令檢查端口是否被占用: 二、修改vsftpd配置文件1. 打開vsftpd配置文件2. 找到并修改端口配置3. 保存并退出4. 重啟vsftpd服務 三、配置防火墻 在Linux系統中修改FTP端口&#xff0…

npm打包內存不足- JavaScript heap out of memory

直接貼出報錯信息 <--- Last few GCs --->[30904:0000010F60FE58E0] 22090 ms: Scavenge 2037.4 (2069.4) -> 2036.4 (2074.2) MB, 2.5 / 0.0 ms (average mu 0.228, current mu 0.216) allocation failure [30904:0000010F60FE58E0] 22101 ms: Scavenge 2…

AI大語言模型破譯“未知未知”的密鑰:開源情報、被動收入與智能體協作的深層機理與實踐

在人類認識世界的漫長征程中&#xff0c;信息與知識的獲取和運用一直是核心驅動力。我們從“一無所知”的狀態&#xff0c;逐漸積累“已知已知”&#xff0c;并在此基礎上識別“已知未知”&#xff0c;設定目標去探索解答。然而&#xff0c;真正能夠帶來范式轉變、顛覆現有格局…

kubelet 清理資源以緩解磁盤壓力

kubelet 資源清理緩解磁盤壓力指南 在 Kubernetes 集群中&#xff0c;當節點磁盤壓力過大時&#xff0c;可通過以下幾種方式利用 kubelet 清理資源&#xff0c;從而緩解磁盤壓力。 一、鏡像垃圾回收 自動回收 kubelet 內置了鏡像垃圾回收機制&#xff0c;其行為由配置參數控…

SPOJ 11576 TRIP2 - A Famous King’s Trip 【Tarjan+歐拉回路】

自我吐槽 &#xff08;哭 題目傳送門 SPOJ 洛谷 題目大意 讓你在簡單無向圖上刪去2條邊&#xff0c;使該圖聯通并存在歐拉回路 輸出字典序最小的一對邊 思路 考慮到存在歐拉回路的充要條件&#xff0c;即 i n x ≡ 0 ( m o d 2 ) ? i ( 1 ≤ i ≤ n ) in_x\equiv 0 (\m…