精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何修剪二叉搜索樹

算法與數(shù)據(jù)結構 ? 來源:代碼隨想錄 ? 作者:程序員Carl ? 2021-10-11 14:16 ? 次閱讀

如果不對遞歸有深刻的理解,本題有點難。單純移除一個節(jié)點那還不夠,要修剪!

669. 修剪二叉搜索樹

給定一個二叉搜索樹,同時給定最小邊界L 和最大邊界 R。通過修剪二叉搜索樹,使得所有節(jié)點的值在[L, R]中 (R>=L) 。你可能需要改變樹的根節(jié)點,所以結果應當返回修剪好的二叉搜索樹的新的根節(jié)點。

思路

相信看到這道題目大家都感覺是一道簡單題(事實上leetcode上也標明是簡單)。

但還真的不簡單!

遞歸法

直接想法就是:遞歸處理,然后遇到root->val < low || root->val > high的時候直接return NULL,一波修改,趕緊利落。

不難寫出如下代碼:

classSolution{
public:
TreeNode*trimBST(TreeNode*root,intlow,inthigh){
if(root==nullptr||root->valval>high)returnnullptr;
root->left=trimBST(root->left,low,high);
root->right=trimBST(root->right,low,high);
returnroot;
}
};

然而[1, 3]區(qū)間在二叉搜索樹的中可不是單純的節(jié)點3和左孩子節(jié)點0就決定的,還要考慮節(jié)點0的右子樹

所以以上的代碼是不可行的!

從圖中可以看出需要重構二叉樹,想想是不是本題就有點復雜了。

其實不用重構那么復雜。

在上圖中我們發(fā)現(xiàn)節(jié)點0并不符合區(qū)間要求,那么將節(jié)點0的右孩子 節(jié)點2 直接賦給 節(jié)點3的左孩子就可以了(就是把節(jié)點0從二叉樹中移除)

理解了最關鍵部分了我們在遞歸三部曲:

這里我們?yōu)槭裁葱枰祷刂的兀?/p>

因為是要遍歷整棵樹,做修改,其實不需要返回值也可以,我們也可以完成修剪(其實就是從二叉樹中移除節(jié)點)的操作。

但是有返回值,更方便,可以通過遞歸函數(shù)的返回值來移除節(jié)點。

這樣的做法在二叉樹:搜索樹中的插入操作二叉樹:搜索樹中的刪除操作中大家已經(jīng)了解過了。

代碼如下:

TreeNode*trimBST(TreeNode*root,intlow,inthigh)
  • 確定終止條件

修剪的操作并不是在終止條件上進行的,所以就是遇到空節(jié)點返回就可以了。

if(root==nullptr)returnnullptr;
  • 確定單層遞歸的邏輯

如果root(當前節(jié)點)的元素小于low的數(shù)值,那么應該遞歸右子樹,并返回右子樹符合條件的頭結點。

代碼如下:

if(root->valright,low,high);//尋找符合區(qū)間[low,high]的節(jié)點
returnright;
}

如果root(當前節(jié)點)的元素大于high的,那么應該遞歸左子樹,并返回左子樹符合條件的頭結點。

代碼如下:

if(root->val>high){
TreeNode*left=trimBST(root->left,low,high);//尋找符合區(qū)間[low,high]的節(jié)點
returnleft;
}

接下來要將下一層處理完左子樹的結果賦給root->left,處理完右子樹的結果賦給root->right。

最后返回root節(jié)點,代碼如下:

root->left=trimBST(root->left,low,high);//root->left接入符合條件的左孩子
root->right=trimBST(root->right,low,high);//root->right接入符合條件的右孩子
returnroot;

此時大家是不是還沒發(fā)現(xiàn)這多余的節(jié)點究竟是如何從二叉樹中移除的呢?

在回顧一下上面的代碼,針對下圖中二叉樹的情況:

如下代碼相當于把節(jié)點0的右孩子(節(jié)點2)返回給上一層,

if(root->valright,low,high);//尋找符合區(qū)間[low,high]的節(jié)點
returnright;
}

然后如下代碼相當于用節(jié)點3的左孩子 把下一層返回的 節(jié)點0的右孩子(節(jié)點2) 接住。

root->left=trimBST(root->left,low,high);

此時節(jié)點3的右孩子就變成了節(jié)點2,將節(jié)點0從二叉樹中移除了。

最后整體代碼如下:

classSolution{
public:
TreeNode*trimBST(TreeNode*root,intlow,inthigh){
if(root==nullptr)returnnullptr;
if(root->valright,low,high);//尋找符合區(qū)間[low,high]的節(jié)點
returnright;
}
if(root->val>high){
TreeNode*left=trimBST(root->left,low,high);//尋找符合區(qū)間[low,high]的節(jié)點
returnleft;
}
root->left=trimBST(root->left,low,high);//root->left接入符合條件的左孩子
root->right=trimBST(root->right,low,high);//root->right接入符合條件的右孩子
returnroot;
}
};

精簡之后代碼如下:

classSolution{
public:
TreeNode*trimBST(TreeNode*root,intlow,inthigh){
if(root==nullptr)returnnullptr;
if(root->valreturntrimBST(root->right,low,high);
if(root->val>high)returntrimBST(root->left,low,high);
root->left=trimBST(root->left,low,high);
root->right=trimBST(root->right,low,high);
returnroot;
}
};

只看代碼,其實不太好理解節(jié)點是符合移除的,這一塊大家可以自己在模擬模擬!

迭代法

因為二叉搜索樹的有序性,不需要使用棧模擬遞歸的過程。

在剪枝的時候,可以分為三步:

  • 將root移動到[L, R] 范圍內,注意是左閉右閉區(qū)間
  • 剪枝左子樹
  • 剪枝右子樹

代碼如下:

classSolution{
public:
TreeNode*trimBST(TreeNode*root,intL,intR){
if(!root)returnnullptr;

//處理頭結點,讓root移動到[L,R]范圍內,注意是左閉右閉
while(root!=nullptr&&(root->valval>R)){
if(root->valright;//小于L往右走
elseroot=root->left;//大于R往左走
}
TreeNode*cur=root;
//此時root已經(jīng)在[L,R]范圍內,處理左孩子元素小于L的情況
while(cur!=nullptr){
while(cur->left&&cur->left->valleft=cur->left->right;
}
cur=cur->left;
}
cur=root;

//此時root已經(jīng)在[L,R]范圍內,處理右孩子大于R的情況
while(cur!=nullptr){
while(cur->right&&cur->right->val>R){
cur->right=cur->right->left;
}
cur=cur->right;
}
returnroot;
}
};

總結

修剪二叉搜索樹其實并不難,但在遞歸法中大家可看出我費了很大的功夫來講解如何刪除節(jié)點的,這個思路其實是比較繞的。

最終的代碼倒是很簡潔。

如果不對遞歸有深刻的理解,這道題目還是有難度的!

本題我依然給出遞歸法和迭代法,初學者掌握遞歸就可以了,如果想進一步學習,就把迭代法也寫一寫。

其他語言版本

Java

classSolution{
publicTreeNodetrimBST(TreeNoderoot,intlow,inthigh){
if(root==null){
returnnull;
}
if(root.valreturntrimBST(root.right,low,high);
}
if(root.val>high){
returntrimBST(root.left,low,high);
}
//root在[low,high]范圍內
root.left=trimBST(root.left,low,high);
root.right=trimBST(root.right,low,high);
returnroot;
}
}

Python

classSolution:
deftrimBST(self,root:TreeNode,low:int,high:int)->TreeNode:
ifnotroot:returnroot
ifroot.valreturnself.trimBST(root.right,low,high)//尋找符合區(qū)間[low,high]的節(jié)點
ifroot.val>high:
returnself.trimBST(root.left,low,high)//尋找符合區(qū)間[low,high]的節(jié)點
root.left=self.trimBST(root.left,low,high)//root->left接入符合條件的左孩子
root.right=self.trimBST(root.right,low,high)//root->right接入符合條件的右孩子
returnroot
責任編輯:haq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 源代碼
    +關注

    關注

    96

    文章

    2942

    瀏覽量

    66443
  • 二叉樹
    +關注

    關注

    0

    文章

    74

    瀏覽量

    12283

原文標題:修剪一棵二叉搜索樹

文章出處:【微信號:TheAlgorithm,微信公眾號:算法與數(shù)據(jù)結構】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    月訪問量超2億,增速113%!360AI搜索成為全球增速最快的AI搜索引擎

    和系統(tǒng)自動匹配最佳模型,這使得360AI搜索獲得了獨一無的技術優(yōu)勢。除了通用大模型,360AI搜索還配備了眾多搜索場景專用模型,精準提升特定場景下的
    的頭像 發(fā)表于 09-09 13:44 ?165次閱讀
    月訪問量超2億,增速113%!360AI<b class='flag-5'>搜索</b>成為全球增速最快的AI<b class='flag-5'>搜索</b>引擎

    指電極上覆蓋敏感材料的阻值計算

    覆蓋的敏感材料厚度超出指厚度時計算電阻,是否可以視作指電極指間電阻多個周期串聯(lián)后與超出指厚度部分敏感材料電阻并聯(lián)
    發(fā)表于 07-05 14:48

    指MOSFET器件靜電防護魯棒性提升技巧

    柵極接地NMOS是一種廣泛應用的片上ESD器件結構,為達到特定ESD防護等級,一般會采用多指版圖形式來減小器件占用的芯片面積。但是,多指柵極接地NMOS在ESD應力作用下,各個指難于做到均勻
    的頭像 發(fā)表于 06-22 00:50 ?359次閱讀
    多<b class='flag-5'>叉</b>指MOSFET器件靜電防護魯棒性提升技巧

    Redis官方搜索引擎來了,性能炸裂!

    RediSearch 是一個 Redis 模塊,為 Redis 提供查詢、級索引和全文搜索功能。
    的頭像 發(fā)表于 02-21 10:01 ?1819次閱讀
    Redis官方<b class='flag-5'>搜索</b>引擎來了,性能炸裂!

    語音數(shù)據(jù)集在智能語音搜索中的應用與挑戰(zhàn)

    揮著重要作用,為系統(tǒng)提供了豐富的語音數(shù)據(jù)和信息,提高了搜索的準確性和效率。本文將詳細介紹語音數(shù)據(jù)集在智能語音搜索中的應用、面臨的挑戰(zhàn)以及未來的發(fā)展趨勢。 、語音數(shù)據(jù)集在智能語音搜索
    的頭像 發(fā)表于 01-18 15:09 ?451次閱讀

    如何修改內核設備

    如何修改內核設備
    的頭像 發(fā)表于 12-14 14:06 ?677次閱讀
    如何修改內核設備<b class='flag-5'>樹</b>

    淺析STP/RSTP協(xié)議(一)

    生成協(xié)議STP(Spanning Tree Protocol)將環(huán)形網(wǎng)絡修剪成為一個無環(huán)的型網(wǎng)絡,避免報文在環(huán)形網(wǎng)絡中的增生和無限循環(huán)。
    的頭像 發(fā)表于 12-08 13:37 ?992次閱讀
    淺析STP/RSTP協(xié)議(一)

    堆的實現(xiàn)思路

    什么是堆? 堆是一種 基于樹結構的數(shù)據(jù)結構,它是一棵二叉樹 ,具有以下兩個特點: 堆是一個完全二叉樹,即除了最后一層,其他層都是滿的,最后一層從左到右填滿。 堆中每個節(jié)點都滿足堆的特性,即父節(jié)點的值
    的頭像 發(fā)表于 11-24 16:02 ?331次閱讀
    堆的實現(xiàn)思路

    二叉樹的定義

    型結構 是一類重要的 非線性數(shù)據(jù)結構 ,其中以二叉樹最為常用,直觀來看,是以分支關系定義的層次結構。型結構在客觀世界中廣泛存在,比
    的頭像 發(fā)表于 11-24 15:57 ?1034次閱讀
    <b class='flag-5'>樹</b>與<b class='flag-5'>二叉樹</b>的定義

    什么情況下需要布隆過濾器

    , gmail等郵箱垃圾郵件過濾功能 這幾個例子有一個共同的特點:如何判斷一個元素是否存在一個集合中? 常規(guī)思路 數(shù)組 鏈表 、平衡二叉樹、Trie Map (紅黑) 哈希表 雖然上面描述的這幾種數(shù)據(jù)結構配合常見的排序、
    的頭像 發(fā)表于 11-11 11:37 ?552次閱讀
    什么情況下需要布隆過濾器

    紅黑的特點及應用

    比起理解紅黑的原理,更重要的是理解紅黑的應用場景,因為某些應用場景的需要,紅黑才會應運而生。 紅黑的特點: 插入,刪除,查找都是O(logn)的復雜度。 紅黑
    的頭像 發(fā)表于 11-10 11:16 ?609次閱讀
    紅黑<b class='flag-5'>樹</b>的特點及應用

    為什么MySQL索引要用B+tree?

    紅黑是一種特化的 AVL(平衡二叉樹),都是在進行插入和刪除操作時通過特定操作保持二叉查找的平衡; 若一棵
    發(fā)表于 10-30 14:41 ?170次閱讀

    文件系統(tǒng)-多二叉樹的轉化

    在這一節(jié)中,我們來學習如何使用程序來實現(xiàn)一棵文件。在上一節(jié)中,我們了解到使用文件的方式來整合計算機中所有的資源,而這一棵文件則是一棵多
    的頭像 發(fā)表于 10-11 10:06 ?768次閱讀
    文件系統(tǒng)-多<b class='flag-5'>叉</b><b class='flag-5'>樹</b>與<b class='flag-5'>二叉樹</b>的轉化

    數(shù)據(jù)結構面試之二叉樹相關操作

    根據(jù)前序可知根結點為1; 根據(jù)中序可知 4 7 2 為根結點 1 的左子樹和 8 5 9 3 6 為根結點 1 的右子樹; 遞歸實現(xiàn),把 4 7 2 當做新的一棵和 8 5 9 3 6 也當做新的一棵; 在遞歸的過程中輸出后序。
    發(fā)表于 10-10 14:50 ?182次閱讀
    數(shù)據(jù)結構面試之<b class='flag-5'>二叉樹</b>相關操作

    物聯(lián)網(wǎng)開發(fā)需要學習哪些內容?

    和需要掌握的技能。 1. 物聯(lián)網(wǎng)軟件開發(fā)必備編程技術: Linux C語言、數(shù)據(jù)結構 核心技能內容: 必備的Linux命令; C語言的基礎知識; C語言的數(shù)組、指針和函數(shù); 數(shù)據(jù)結構中的線性表、棧和隊列用法及實現(xiàn); 二叉樹遞歸遍歷、層次遍歷、及非
    的頭像 發(fā)表于 10-09 17:23 ?1388次閱讀