leetcode題解450:刪除BST中的結點!調整二叉樹的結構最難!

一、題目內容

題目要求刪除二叉搜索樹(BST)中值為 key 的節點,并保證刪除后二叉搜索樹的性質不變。返回刪除節點后的二叉搜索樹的根節點的引用。一般來說,刪除節點可分為兩個步驟:首先找到需要刪除的節點;如果找到了,刪除它。

二、題目分析

(一)輸入和輸出

輸入:二叉搜索樹的根節點 root 和待刪除的值 key。

輸出:刪除指定值節點后二叉搜索樹的根節點。

(二)遞歸函數 deleteNode 的邏輯

基本情況:如果當前節點為空(root == NULL),說明沒有找到需要刪除的節點,直接返回 NULL。

如果當前節點的值等于 key(root->val == key),則需要根據當前節點的子節點情況來決定如何刪除:

  1. 如果當前節點是葉子節點(root->left == NULL && root->right == NULL),直接刪除當前節點并返回 NULL。

  2. 如果當前節點只有一個右子節點(root->left == NULL && root->right != NULL),刪除當前節點并返回其右子節點。

  3. 如果當前節點只有一個左子節點(root->left != NULL && root->right == NULL),刪除當前節點并返回其左子節點。

  4. 如果當前節點既有左子節點又有右子節點,找到當前節點右子樹的最左節點(即右子樹中的最小值節點),將其左子樹連接到該最左節點的左子樹上,然后刪除當前節點并返回其右子節點。

遞歸邏輯:如果當前節點的值大于 key(root->val > key),則遞歸地在左子樹中刪除 key 對應的節點;如果當前節點的值小于 key(root->val < key),則遞歸地在右子樹中刪除 key 對應的節點。遞歸返回后,將返回的子樹節點賦值給當前節點的左或右子節點。

三、解題要點

(一)二叉搜索樹的定義

二叉搜索樹是一種特殊的二叉樹,其性質是:對于任意節點,其左子樹上所有節點的值都小于該節點的值,其右子樹上所有節點的值都大于該節點的值。這一性質是刪除操作的基礎,刪除操作需要保持這一性質不變。

(二)刪除操作的性質

刪除操作需要保持二叉搜索樹的性質不變。刪除節點后,樹的結構需要重新調整,以確保仍然滿足二叉搜索樹的性質。

(三)解題思路

1.基本情況

如果當前節點為空(root == NULL),說明沒有找到需要刪除的節點,直接返回 NULL。這是遞歸的終止條件。

2.遞歸邏輯

比較當前節點值與待刪除值:

如果當前節點的值等于 key(root->val == key),根據當前節點的子節點情況來決定如何刪除。

如果當前節點的值大于 key(root->val > key),則遞歸地在左子樹中刪除 key 對應的節點。

如果當前節點的值小于 key(root->val < key),則遞歸地在右子樹中刪除 key 對應的節點。

更新子樹:遞歸返回后,將返回的子樹節點賦值給當前節點的左或右子節點。這一步確保了遞歸返回后,當前節點的子樹被正確更新。

3.遞歸返回

遞歸返回時,返回當前節點。這一步確保了遞歸調用的正確性,使得每次遞歸返回后,當前節點的狀態被正確恢復,不會影響后續的遞歸調用。

四、代碼解答

class Solution {
public:TreeNode* deleteNode(TreeNode* root, int key) {// 如果當前節點為空,直接返回 NULLif (root == NULL) return NULL;// 如果當前節點的值等于 key,根據子節點情況決定如何刪除if (root->val == key) {// 如果當前節點是葉子節點,直接刪除并返回 NULLif (root->left == NULL && root->right == NULL) {delete root;return NULL;}// 如果當前節點只有一個右子節點,刪除當前節點并返回其右子節點else if (root->left == NULL && root->right != NULL) {TreeNode* temp = root->right;delete root;return temp;}// 如果當前節點只有一個左子節點,刪除當前節點并返回其左子節點else if (root->left != NULL && root->right == NULL) {TreeNode* temp = root->left;delete root;return temp;}// 如果當前節點既有左子節點又有右子節點else {// 找到當前節點右子樹的最左節點TreeNode* cur = root->right;while (cur->left != NULL) {cur = cur->left;}// 將當前節點的左子樹連接到最左節點的左子樹上cur->left = root->left;// 刪除當前節點并返回其右子節點TreeNode* temp = root->right;delete root;return temp;}}// 如果當前節點的值大于 key,遞歸地在左子樹中刪除 key 對應的節點if (root->val > key) {root->left = deleteNode(root->left, key);}// 如果當前節點的值小于 key,遞歸地在右子樹中刪除 key 對應的節點else {root->right = deleteNode(root->right, key);}// 返回當前節點return root;}
};

五、詳細注釋

(一)遞歸函數 deleteNode

基本情況:如果當前節點為空,直接返回 NULL。

如果當前節點的值等于 key,根據當前節點的子節點情況來決定如何刪除。

遞歸邏輯:如果當前節點的值大于 key,遞歸地在左子樹中刪除 key 對應的節點;如果當前節點的值小于 key,遞歸地在右子樹中刪除 key 對應的節點。遞歸返回后,將返回的子樹節點賦值給當前節點的左或右子節點。

六、回溯和遞歸的詳細解釋

(一)遞歸

遞歸是一種函數調用自身的方法,用于解決復雜問題。在本題中,遞歸用于逐層檢查每個節點,找到需要刪除的節點,并根據情況調整樹的結構。遞歸的核心思想是將問題分解為更小的子問題,通過解決子問題來解決原問題。

(二)終止條件

遞歸的終止條件是當前節點為空,此時直接返回 NULL。這是遞歸的出口,確保遞歸不會無限進行下去。

(三)回溯

在遞歸調用返回后,通過返回值恢復到當前節點的狀態,確保每次遞歸返回后,狀態正確,不會影響后續的遞歸調用。

在本題中,回溯的過程主要體現在以下幾個方面:

  1. 遞歸調用的返回值:每個遞歸分支都會返回一個節點,這個節點可以是刪除操作后的子樹的根節點,也可以是 NULL。

  2. 返回值的處理:在每個遞歸調用返回后,當前節點會根據返回值來決定下一步的操作:

    • 如果當前節點的值大于 key,將返回值賦值給當前節點的左子節點。

    • 如果當前節點的值小于 key,將返回值賦值給當前節點的右子節點。

(四)遞歸調用的詳細過程

  1. 初始調用:從根節點開始調用 deleteNode(root, key)。

  2. 遞歸調用:如果 root->val > key,遞歸調用 deleteNode(root->left, key);如果 root->val < key,遞歸調用 deleteNode(root->right, key)。

  3. 終止條件:當遞歸調用到達一個空節點時,直接返回 NULL。

  4. 回溯過程:遞歸返回后,將返回的子樹節點賦值給當前節點的左或右子節點。遞歸返回到上一層調用,繼續處理上一層的節點,直到返回到根節點。

(五)代碼執行過程示例

假設我們有一個二叉搜索樹,根節點為 root,值為 5,其左子節點值為 3,右子節點值為 7。現在要刪除值為 3 的節點。

  1. 初始調用:deleteNode(root, 3)。

  2. 當前節點值為 5,3 < 5,遞歸調用 deleteNode(root->left, 3)。

  3. 遞歸調用:deleteNode(root->left, 3)。

  4. 當前節點值為 3,3 == 3,進入刪除邏輯:

    • 當前節點只有一個左子節點,刪除當前節點并返回其左子節點。

  5. 回溯過程:

    • 返回到 root,將返回的左子節點

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

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

相關文章

讓 Kubernetes (K8s) 集群 使用 GPU

要讓 Kubernetes (K8s) 集群 使用 GPU&#xff0c;并且節點是 KVM 虛擬化 出來的&#xff0c;需要確保以下幾點&#xff1a; KVM 虛擬機透傳 GPU&#xff08;PCIe Passthrough&#xff09; 宿主機和 K8s 節點正確安裝 NVIDIA 驅動 K8s 集群安裝 nvidia-device-plugin Pod 配…

Android第十七次面試總結(Java數據結構)

一、Java 集合體系核心架構與高頻考點 1. 集合體系架構圖 Java集合框架 ├─ Collection&#xff08;單列集合&#xff09; │ ├─ List&#xff08;有序、可重復&#xff09; │ │ ├─ ArrayList&#xff08;動態數組&#xff0c;隨機訪問快&#xff09; │ │ ├─…

Linux 刪除登錄痕跡

本文介紹相對徹底的刪除 Linux 的登錄痕跡&#xff0c;操作前確保已經可以拿到能提權ROOT令牌的系統管理權限。 當然&#xff0c;仍可以先查閱以下文章。 Linux 刪除用戶終端命令行操作記錄-CSDN博客 1、清楚當前會話記錄 history -c # 清空當前終端內存中的歷史命令 2、永…

Lighttpd 配置選項介紹

根據提供的 Lighttpd 配置選項文檔&#xff08;https://redmine.lighttpd.net/projects/lighttpd/wiki/Docs_ConfigurationOptions &#xff09;&#xff0c;以下是所有配置選項的詳細解釋、作用及適用場景&#xff0c;按模塊分組說明&#xff1a; 以下是對 Lighttpd 配置選項 …

解決本地部署 SmolVLM2 大語言模型運行 flash-attn 報錯

出現的問題 安裝 flash-attn 會一直卡在 build 那一步或者運行報錯 解決辦法 是因為你安裝的 flash-attn 版本沒有對應上&#xff0c;所以報錯&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下載對應版本&#xff0c;cu、torch、cp 的版本一定要對…

Python 訓練營打卡 Day 40-訓練和測試的規范寫法

一.單通道圖片的規范寫法 以之前的MNIST數據集為例 import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader , Dataset # DataLoader 是 PyTorch 中用于加載數據的工具 from torchvision import datasets, transforms # t…

Java 枚舉(Enum)的使用說明

在 Java 中&#xff0c;枚舉&#xff08;Enum&#xff09;是一種特殊的數據類型&#xff0c;用于定義一組固定的命名常量。它比傳統的常量&#xff08;如 public static final&#xff09;更安全、更靈活&#xff0c;且支持面向對象特性。以下是枚舉的詳細用法&#xff1a; 1. …

Docker部署Nginx-UI

使用如下命令拉取運行nginx-ui軟件 docker run -dit \ --namenginx-ui \ --restartalways \ -e TZAsia/Shanghai \ -v /mnt/user/appdata/nginx:/etc/nginx \ -v /mnt/user/appdata/nginx-ui:/etc/nginx-ui \ -v /var/run/docker.sock:/var/run/docker.sock \ -…

OkHttp 3.0源碼解析:從設計理念到核心實現

本文通過深入分析OkHttp 3.0源碼&#xff0c;揭示其高效HTTP客戶端的實現奧秘&#xff0c;包含核心設計理念、關鍵組件解析、完整工作流程及實用技巧。 一、引言&#xff1a;為什么選擇OkHttp&#xff1f; 在Android和Java生態中&#xff0c;OkHttp已成為HTTP客戶端的標準選擇…

洛谷P12170 [藍橋杯 2025 省 Python B] 攻擊次數

題目傳送門 思路 首先定義一個數 n n n ,初值為 2025 2025 2025,從第一回合開始,三個英雄持續攻擊,攻擊方式為: 第一個英雄: 每回合攻擊 5 5 5

百度之星2021——BD202104 萌新

輸入格式&#xff1a; 本題有多組測試數據。 第一行一個數 T (1 ≤ T ≤ 1000) 表示一共有 T 組數據。對于每一組數據&#xff0c;輸入一行兩個數 a,b (1 ≤ a,b ≤ 1000000000)。 輸出格式&#xff1a; 對每組數據&#xff0c;輸出一行兩個數分別表示最小與最大的 c&#xff0…

R語言ICU患者死亡率預測實戰

【圖書推薦】《R語言醫學數據分析實踐》-CSDN博客 《R語言醫學數據分析實踐 李丹 宋立桓 蔡偉祺 清華大學出版社9787302673484》【摘要 書評 試讀】- 京東圖書 (jd.com) 預測ICU患者死亡率對比較藥物的療效、比較護理的有效性、比較手術的有效性有重要意義&#xff0c;利用機…

leetcode240-搜索二維矩陣

leetcode 240 思路 1. 矩陣特性 首先&#xff0c;利用矩陣的特性是解題的關鍵&#xff1a; 每行的元素遞增每列的元素遞增 這意味著&#xff0c;如果我們在矩陣中從右上角或左下角開始搜索&#xff0c;可以有效縮小搜索范圍 2. 從右上角開始搜索 將搜索的起點定位在矩陣…

Linux相關概念和易錯知識點(42)(TCP的連接管理、可靠性、面臨復雜網絡的處理)

目錄 1.TCP的連接管理機制&#xff08;1&#xff09;三次握手①握手過程②對握手過程的理解 &#xff08;2&#xff09;四次揮手&#xff08;3&#xff09;握手和揮手的觸發&#xff08;4&#xff09;狀態切換①揮手過程中狀態的切換②握手過程中狀態的切換 2.TCP的可靠性&…

【web應用】若依框架:若依框架中的頁面跳轉簡介

文章目錄 ?前言1. 后端控制器跳轉2. 前端路由跳轉3. 菜單配置跳轉4. 權限控制跳轉5. 常見跳轉路徑 ?一、主目錄頁面跳轉?二、菜單目錄跳轉?總結 標題詳情作者JosieBook頭銜CSDN博客專家資格、阿里云社區專家博主、軟件設計工程師博客內容開源、框架、軟件工程、全棧&#x…

MS9292+MS9332 HD/DVI轉VGA轉換器+HD環出帶音頻

MS9292MS9332是一款HD/DVI轉VGA轉換器HD環出帶音頻的視頻轉換方案。支持HD/DVI輸入&#xff0c;VGA輸出和HD環出&#xff0c;HD/DVI輸入最高支持1920120060Hz&#xff0c;VGA輸出最高支持1920120060Hz&#xff0c;HD環出最高支持4K30Hz。該方案已實現量產&#xff0c;并提供完善…

C++初階-list的模擬實現(難度較高)

1.list&#xff08;容器&#xff0c;不是類&#xff09;模擬實現基本結構 這個實現是和源碼的實現不同的&#xff0c;不要進行強制類型轉換了&#xff0c;很麻煩。我們把定義放在.h文件中&#xff0c;在.cpp中放測試代碼。 注&#xff1a;這個基本結構之后會改變&#xff0c;…

【ROS】Nav2源碼之nav2_behavior_tree-行為樹節點列表

1、行為樹節點分類 在 Nav2(Navigation2)的行為樹框架中,行為樹節點插件按照功能分為 Action(動作節點)、Condition(條件節點)、Control(控制節點) 和 Decorator(裝飾節點) 四類。 1.1 動作節點 Action 執行具體的機器人操作或任務,直接與硬件、傳感器或外部系統…

【iOS】cell的復用以及自定義cell

【iOS】cell的復用以及自定義cell 文章目錄 【iOS】cell的復用以及自定義cell前言cell的復用手動&#xff08;非注冊&#xff09;自動&#xff08;注冊&#xff09; 自定義cell 前言 cell的復用及自定義cell是UITableView或UICollectionView的一個重要優化機制,當用戶滾動視圖…

深度學習之模型壓縮三駕馬車:基于ResNet18的模型剪枝實戰(2)

前言 《深度學習之模型壓縮三駕馬車&#xff1a;基于ResNet18的模型剪枝實戰&#xff08;1&#xff09;》里面我只是提到了對conv1層進行剪枝&#xff0c;只是為了驗證這個剪枝的整個過程&#xff0c;但是后面也有提到&#xff1a;僅裁剪 conv1層的影響極大&#xff0c;原因如…