代碼隨想錄算法訓練營第60期第二十天打卡

? ? ? ? 大家好,今天我們繼續進入二叉樹的章節,二叉樹章節應該已經過半了,大家再堅持一下,那么廢話不多說,我們繼續今天的內容。

第一題對應力扣編號為235的二叉搜索樹的最近公共祖先

? ? ? ? 其實我們上次任務就接觸過了二叉樹的最近公共祖先,其實很難,我們很容易就迷糊我們究竟如何返回以及什么情況下才會有最近公共祖先,其實最近的公共祖先就是兩個節點分別處在最近的左右子樹中,兩邊均返回true這種情況下我們就找到了最近公共祖先,那我們知道二叉搜索樹是一種特殊的二叉樹,那么它的最近公共祖先應該如何找呢?我們一起走進我們今天的第一題:

? ? ? 其實這跟我們上次的二叉樹的最近公共祖先是一樣的要求,我們原來的思路是自底向上回溯,遇到一個節點的左子樹里有p,右子樹里有q,那么當前節點就是最近公共祖先。很明顯我們應該好好利用二叉搜索樹的特點來助力我們解決這道題目,因為是有序樹,所以 如果 中間節點是 q 和 p 的公共祖先,那么 中節點的數組 一定是在 [p, q]區間的。即 中節點 > p && 中節點 < q 或者 中節點 > q && 中節點 < p。我們可以利用這個二叉搜索樹的性質,但是我們會思考我們這樣找到的節點究竟是不是最近的公共祖先,我給出大家一個代碼隨想錄上的例子:

? ? ? ?其實我們可以看到p,q的最近公共祖先是5,通過圖我們可以看到如何我們從5向左遍歷我們將會失去成為p的祖先的可能,同理如果我們向右遍歷我們將會失去成為q的祖先的可能,所以當我們從上向下去遞歸遍歷,第一次遇到 cur節點是數值在[q, p]區間中,那么cur就是 q和p的最近公共祖先。因此我們可以得到如果我們從上往下遍歷如果我們第一次遇到 cur節點是數值在[q, p]區間中,那么cur就是 q和p的最近公共祖先。那我們就嘗試寫一下遞歸代碼,首先大家要明白單層遞歸的邏輯,如果我當前節點的值比p,q兩個節點的值都要小的話說明我們要尋找的目標應該是右邊,我們應該向右遍歷,相反如果我當前節點的值比p,q兩個節點的值都要大的話說明我們要尋找的目標應該是左邊,我們應該向左遍歷,因此這個二叉搜索樹由于有順序我們從上往下遞歸也是可以實現的,我們嘗試寫一下代碼:

class Solution {
private:TreeNode* traversal(TreeNode *cur, TreeNode* p, TreeNode *q){if (cur == NULL) return NULL;//這時候我們的搜索目標應該是在左邊if (cur -> val > p -> val && cur -> val > q -> val){TreeNode* left = traversal(cur -> left, p, q);if (left != NULL) return left;}if (cur -> val < p -> val && cur -> val < q -> val){TreeNode* right = traversal(cur -> right, p, q);if (right != NULL) return right;}return cur;//如果一邊大一邊小就說明這就是最近公共祖先了}
public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {return traversal(root, p, q);}
};

? ? ? ?這個代碼只要大家理解了我上面的思路就不難了,還是二叉搜索樹的特殊性質很重要。我們這道題就講解到這里,接下來我們進入下一道題目。

第二題對應力扣編號為701的題目二叉搜索樹中的插入操作

? ? ? ?我們來到了今天的第二題,這個是關于二叉搜索樹的插入操作,我們直接看到題目的具體要求:

? ? ? ? 要解決這道題目我感覺我們要明白的是我們應該考慮往左邊插還是往右邊插,這個其實我們還是得考慮二叉搜索樹的性質,那我們應該如何考慮呢?其實題目不算難,我們返回有效的結果就可以,也就是我們找到適合的插入位置并且這個地方是空節點我們就可以插入,那其實我們還是遞歸的過程,首先有一種特殊的情況如果我們的根節點是空節點我們就直接把題目中給出的節點插入到空節點就可以了,大家一起來看一看我們的遞歸代碼:

class Solution {
public:TreeNode* insertIntoBST(TreeNode* root, int val) {if (root == NULL){TreeNode *node = new TreeNode(val);return node;}if (root -> val > val){root -> left = insertIntoBST(root -> left, val);}else if (root -> val < val){root -> right = insertIntoBST(root -> right, val);}else return root;return root;}
};

? ? ? ? 我們還是搞明白我們插入的邏輯,首先就是空節點的話我們就直接插入到空節點就可以,如果我給出的值比根節點小,就說明我當前的值應該往左邊插入,如果我給出的值比根節點大,就說明我當前的值應該往右邊插入,如果相等我也無需插入了直接返回根節點了,根節點就可以取代我這個節點,這樣這個題目我們就解決了,相信大家可以明白,這道題難度不大,我們要進入下一道題目了。

第三題對應力扣編號為450的題目刪除二叉樹中的節點

? ? ? ?其實這跟上一道題目不就是異曲同工嗎?上一題我們需要插入,這一題我們刪除,我們就直接進入這道題目:

? ? ? ? ?首先還是我們得找到這個節點否則我們刪什么呢?還是遞歸對吧,我們要找到要刪除的節點,這里有一個地方很難,就是我調整二叉樹的時候不好理解,我要分的幾種情況我都在代碼注釋里給大家寫清楚了:

class Solution {
public:TreeNode* deleteNode(TreeNode* root, int key) {if (root == nullptr) return root; // 第一種情況:沒找到刪除的節點,遍歷到空節點直接返回了if (root->val == key) {// 第二種情況:左右孩子都為空(葉子節點),直接刪除節點, 返回NULL為根節點if (root->left == nullptr && root->right == nullptr) {///! 內存釋放delete root;return nullptr;}// 第三種情況:其左孩子為空,右孩子不為空,刪除節點,右孩子補位 ,返回右孩子為根節點else if (root->left == nullptr) {auto retNode = root->right;///! 內存釋放delete root;return retNode;}// 第四種情況:其右孩子為空,左孩子不為空,刪除節點,左孩子補位,返回左孩子為根節點else if (root->right == nullptr) {auto retNode = root->left;///! 內存釋放delete root;return retNode;}// 第五種情況:左右孩子節點都不為空,則將刪除節點的左子樹放到刪除節點的右子樹的最左面節點的左孩子的位置// 并返回刪除節點右孩子為新的根節點。else {TreeNode* cur = root->right; // 找右子樹最左面的節點while(cur->left != nullptr) {cur = cur->left;}cur->left = root->left; // 把要刪除的節點(root)左子樹放在cur的左孩子的位置TreeNode* tmp = root;   // 把root節點保存一下,下面來刪除root = root->right;     // 返回舊root的右孩子作為新rootdelete tmp;             // 釋放節點內存(這里不寫也可以,但C++最好手動釋放一下吧)return root;}}if (root->val > key) root->left = deleteNode(root->left, key);if (root->val < key) root->right = deleteNode(root->right, key);return root;}
};

? ? ? 我重點講解最后的else的情況,就是左右子樹都不為空的時候我們刪除了節點我們應該如何調整這棵搜索二叉樹,這個相當難,我們舉個例子來理解一下:

? ? ? ?比方說這棵二叉樹,我們要刪除7這個節點的話我們不得不讓其左孩子或者右孩子繼位,但是我們知道二叉搜索樹的話節點7它的左子樹的值都是小于7的,右子樹的值都是大于7的,我們讓7的右孩子繼位,如果7沒了我們的左子樹就要去尋找新的父節點,我們選擇的是比7大一點的節點就是了,因此這個位置我們就找到了右子樹的最左邊的位置,這樣才可以保證我們將7刪除之后我所組成的二叉樹還是一棵二叉搜索樹,這就是本道題目最難想的地方,那我們也看一下它的代碼實現,代碼里前面的幾種情況都是很簡單的,上面代碼的注釋我也清晰標注了,關鍵看這種情況,首先拿到右孩子,讓右孩子繼承父節點的位置,接下來我們要安頓好原先父節點的左子樹,我們選擇的是右子樹的最左邊的位置,我們借助一個變量來保存父節點,然后我們將右孩子賦值給根節點,最后返回根節點就可以了,最后大家還要注意遞歸,什么情況下往左遞歸,什么情況下往右遞歸,這道題我就先給大家解釋道這里。

總結

? ? ? ? ?今天的二叉搜索樹的最近公共祖先其實不難,比普通的要簡單一些,因為它有獨特的性質,二叉搜索樹插入節點簡單的原因是我們不需要改變二叉搜索樹的結構,刪除就難在我們要去改變二叉搜索樹的結構,

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

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

相關文章

8.0 西門子PLC的S7通訊解析

PC與西門子PLC的S7通訊主要有如下幾個步驟: 1. TCP的三次握手(由Socket對象自動完成) 2.發送訪問請求:COTP 3. 交換通訊信息:setup Commnunication 一、發送訪問請求:COTP 比如向PLC請求+以及PLC返回響應的一個實際例子如下: 發送PLC:----> 03 00 00 16 11 E0 …

Nacos-SpringBoot 配置無法自動刷新問題排查

背景 Nacos SpringBoot版本中&#xff0c;提供了NacosValue注解&#xff0c;支持控制臺修改值時&#xff0c;自動刷新&#xff0c;但是今天遇見了無法自動刷新的問題。 環境 SpringBoot 2.2.x nacos-client&#xff1a;2.1.0 nacos-config-spring-boot-starter&#xff1a;0…

JAVA | 聚焦 OutOfMemoryError 異常

個人主頁 文章專欄 在正文開始前&#xff0c;我想多說幾句&#xff0c;也就是吐苦水吧…最近這段時間一直想寫點東西&#xff0c;停下來反思思考一下。 心中萬言&#xff0c;真正執筆時又不知先寫些什么。通常這個時候&#xff0c;我都會隨便寫寫&#xff0c;文風極像散文&…

基于開源技術體系的品牌賽道力重構:AI智能名片與S2B2C商城小程序源碼驅動的品類創新機制研究

摘要&#xff1a;在數字經濟與實體經濟深度融合的背景下&#xff0c;品牌競爭已從單一產品力競爭轉向生態化、技術化的賽道力競爭。本文以開源AI大模型、AI智能名片及S2B2C商城小程序源碼為核心技術載體&#xff0c;構建"技術賦能-場景貫通-生態協同"三維分析框架&am…

【vue3】購物車實戰:從狀態管理到用戶體驗的全流程實現

在電商項目中&#xff0c;購物車是核心功能之一&#xff0c;需要兼顧數據一致性、用戶體驗和邏輯復雜度。 本文結合 Vue3 Pinia 技術棧&#xff0c;詳細講解如何實現一個高效且易用的購物車系統&#xff0c;重點剖析 添加購物車 和 頭部購物車預覽 的核心邏輯與實現細節。 一…

卡洛詩西餐廳,以“中式西餐”為核心戰略

在餐飲市場的激烈競爭中&#xff0c;“本土化”是許多國際餐飲品牌難以跨越的鴻溝——要么因水土不服黯然退場&#xff0c;要么因過度妥協失去特色。然而&#xff0c;卡洛詩以“中式西餐”為核心戰略&#xff0c;將西餐與國內飲食文化深度融合&#xff0c;不僅破解了西餐本土化…

28-29【動手學深度學習】批量歸一化 + ResNet

1. 批量歸一化 1.1 原理 當神經網絡比較深的時候會發現&#xff1a;數據在下面&#xff0c;損失函數在上面&#xff0c;這樣會出現什么問題&#xff1f; 正向傳遞的時候&#xff0c;數據是從下往上一步一步往上傳遞反向傳遞的時候&#xff0c;數據是從上面往下傳遞&#xff0…

【Linux網絡】Http服務優化 - 增加請求后綴、狀態碼描述、重定向、自動跳轉及注冊多功能服務

&#x1f4e2;博客主頁&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;博客倉庫&#xff1a;https://gitee.com/JohnKingW/linux_test/tree/master/lesson &#x1f4e2;歡迎點贊 &#x1f44d; 收藏 ?留言 &#x1f4dd; 如有錯誤敬請指正&#xff01; &…

AIGC(生成式AI)試用 32 -- AI做軟件程序測試 3

總結之前的AI做程序測試過程&#xff0c;試圖優化提問方式&#xff0c;整合完成的AI程序測試提問&#xff0c;探索更多可能的AI測試 AIGC&#xff08;生成式AI&#xff09;試用 30 -- AI做軟件程序測試 1 AIGC&#xff08;生成式AI&#xff09;試用 31 -- AI做軟件程序…

C語言實現迪杰斯特拉算法進行路徑規劃

使用C語言實現迪杰斯特拉算法進行路徑規劃 迪杰斯特拉算法是一種用于尋找加權圖中最短路徑的經典算法。它特別適合用于計算從一個起點到其他所有節點的最短路徑&#xff0c;前提是圖中的邊權重為非負數。 一、迪杰斯特拉算法的基本原理 迪杰斯特拉算法的核心思想是“貪心法”…

引領印尼 Web3 變革:Mandala Chain 如何助力 1 億用戶邁向數字未來?

當前 Web3 的發展正處于關鍵轉折點&#xff0c;行業亟需吸引新用戶以推動 Web3 的真正大規模采用。然而&#xff0c;大規模采用面臨著核心挑戰&#xff1a;數據泄露風險、集中存儲的安全漏洞、跨系統互操作性障礙&#xff0c;以及低效的服務訪問等問題。如何才能真正突破這些瓶…

WebSocket是h5定義的,雙向通信,節省資源,更好的及時通信

瀏覽器和服務器之間的通信更便利&#xff0c;比http的輪詢等效率提高很多&#xff0c; WebSocket并不是權限的協議&#xff0c;而是利用http協議來建立連接 websocket必須由瀏覽器發起請求&#xff0c;協議是一個標準的http請求&#xff0c;格式如下 GET ws://example.com:3…

Kaamel白皮書:IoT設備安全隱私評估實踐

1. IoT安全與隱私領域的現狀與挑戰 隨著物聯網技術的快速發展&#xff0c;IoT設備在全球范圍內呈現爆發式增長。然而&#xff0c;IoT設備帶來便捷的同時&#xff0c;也引發了嚴峻的安全與隱私問題。根據NSF&#xff08;美國國家科學基金會&#xff09;的研究表明&#xff0c;I…

php安裝swoole擴展

PHP安裝swoole擴展 Swoole官網 安裝準備 安裝前必須保證系統已經安裝了下列軟件 4.8 版本需要 PHP-7.2 或更高版本5.0 版本需要 PHP-8.0 或更高版本6.0 版本需要 PHP-8.1 或更高版本gcc-4.8 或更高版本makeautoconf 安裝Swool擴展 安裝官方文檔安裝后需要再php.ini中增加…

服務器傳輸數據存儲數據建議 傳輸慢的原因

一、JSON存儲的局限性 1. 性能瓶頸 全量讀寫&#xff1a;JSON文件通常需要整體加載到內存中才能操作&#xff0c;當數據量大時&#xff08;如幾百MB&#xff09;&#xff0c;I/O延遲和內存占用會顯著增加。 無索引機制&#xff1a;查找數據需要遍歷所有條目&#xff08;時間復…

Android四大核心組件

目錄 一、為什么需要四大組件&#xff1f; 二、Activity&#xff1a;看得見的界面 核心功能 生命周期圖解 代碼示例 三、Service&#xff1a;看不見的勞動者 兩大類型 生命周期對比 注意陷阱 四、BroadcastReceiver&#xff1a;消息傳遞專員 兩種注冊方式 廣播類型 …

「Mac暢玩AIGC與多模態01」架構篇01 - 展示層到硬件層的架構總覽

一、概述 AIGC&#xff08;AI Generated Content&#xff09;系統由多個結構層級組成&#xff0c;自上而下涵蓋交互界面、API 通信、模型推理、計算框架、底層驅動與硬件支持。本篇梳理 AIGC 應用的六層體系結構&#xff0c;明確各組件在系統中的職責與上下游關系&#xff0c;…

[MERN 項目實戰] MERN Multi-Vendor 電商平臺開發筆記(v2.0 從 bug 到結構優化的工程記錄)

[MERN 項目實戰] MERN Multi-Vendor 電商平臺開發筆記&#xff08;v2.0 從 bug 到結構優化的工程記錄&#xff09; 其實之前沒想著這么快就能把 2.0 的筆記寫出來的&#xff0c;之前的預期是&#xff0c;下一個階段會一直維持到將 MERN 項目寫完&#xff0c;畢竟后期很多東西都…

互斥量函數組

頭文件 #include <pthread.h> pthread_mutex_init 函數原型&#xff1a; int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr); 函數參數&#xff1a; mutex&#xff1a;指向要初始化的互斥量的指針。 attr&#xf…

互聯網的下一代脈搏:深入理解 QUIC 協議

互聯網的下一代脈搏&#xff1a;深入理解 QUIC 協議 互聯網是現代社會的基石&#xff0c;而數據在其中高效、安全地傳輸是其運轉的關鍵。長期以來&#xff0c;傳輸層的 TCP&#xff08;傳輸控制協議&#xff09;一直是互聯網的主力軍。然而&#xff0c;隨著互聯網應用場景的日…