色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

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

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

3天內不再提示

如何修剪二叉搜索樹

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

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

669. 修剪二叉搜索樹

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

思路

相信看到這道題目大家都感覺是一道簡單題(事實上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]區間在二叉搜索樹的中可不是單純的節點3和左孩子節點0就決定的,還要考慮節點0的右子樹。

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

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

其實不用重構那么復雜。

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

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

  • 確定遞歸函數的參數以及返回值

這里我們為什么需要返回值呢?

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

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

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

代碼如下:

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

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

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

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

代碼如下:

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

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

代碼如下:

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

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

最后返回root節點,代碼如下:

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

此時大家是不是還沒發現這多余的節點究竟是如何從二叉樹中移除的呢?

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

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

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

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

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

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

最后整體代碼如下:

classSolution{
public:
TreeNode*trimBST(TreeNode*root,intlow,inthigh){
if(root==nullptr)returnnullptr;
if(root->valright,low,high);//尋找符合區間[low,high]的節點
returnright;
}
if(root->val>high){
TreeNode*left=trimBST(root->left,low,high);//尋找符合區間[low,high]的節點
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;
}
};

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

迭代法

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

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

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

代碼如下:

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已經在[L,R]范圍內,處理左孩子元素小于L的情況
while(cur!=nullptr){
while(cur->left&&cur->left->valleft=cur->left->right;
}
cur=cur->left;
}
cur=root;

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

總結

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

最終的代碼倒是很簡潔。

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

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

其他語言版本

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)//尋找符合區間[low,high]的節點
ifroot.val>high:
returnself.trimBST(root.left,low,high)//尋找符合區間[low,high]的節點
root.left=self.trimBST(root.left,low,high)//root->left接入符合條件的左孩子
root.right=self.trimBST(root.right,low,high)//root->right接入符合條件的右孩子
returnroot
責任編輯:haq

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

    關注

    96

    文章

    2948

    瀏覽量

    67206
  • 二叉樹
    +關注

    關注

    0

    文章

    74

    瀏覽量

    12433

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

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

收藏 人收藏

    評論

    相關推薦

    神經網絡壓縮框架 (NNCF) 中的過濾器修剪統計數據怎么查看?

    無法觀察神經網絡壓縮框架 (NNCF) 中的過濾器修剪統計數據
    發表于 03-06 07:10

    求解答,設備問題

    請問,rk3588j要再提取一個USB3.0接口設備怎么改
    發表于 02-20 11:22

    百度搜索全量上線DeepSeek滿血版,開啟AI搜索新體驗

    近日,百度搜索迎來了重大更新,全量上線了DeepSeek滿血版。這一更新意味著用戶現在可以在百度App中體驗到更加智能、高效的搜索服務。 用戶只需在百度App中輸入任意搜索詞,完成一輪搜索
    的頭像 發表于 02-18 15:15 ?600次閱讀

    百度搜索與文心智能體平臺接入DeepSeek及文心大模型深度搜索

    近日,百度搜索與文心智能體平臺聯合宣布了一項重要更新:將全面接入DeepSeek及文心大模型最新的深度搜索功能。這一更新將為用戶和開發者帶來更加智能、高效的搜索和智能體創建體驗。 據悉,搜索
    的頭像 發表于 02-17 09:14 ?278次閱讀

    Kaggle知識點:7種超參數搜索方法

    數據科學超參數搜索確實是機器學習生命周期中不可或缺的一步,特別是在模型性能方面。正確的超參數選擇可以顯著提高模型的準確性、對未見數據的泛化能力以及收斂速度。不當的超參數選擇可能導致過擬合或欠擬合等
    的頭像 發表于 02-08 14:28 ?465次閱讀
    Kaggle知識點:7種超參數<b class='flag-5'>搜索</b>方法

    嵌入式學習-飛凌嵌入式ElfBoard ELF 1板卡-初識設備之設備組成和結構

    的name和value。在設備中,可描述的信息包括:一、CPU的數量和類別;、內存基地址和大小;三、總線和橋;四、外設連接;五、中斷控制器和中斷使用情況;六、GPIO控制器和GPIO使用情況;七
    發表于 01-08 08:32

    飛凌嵌入式ElfBoard ELF 1板卡-初識設備之設備組成和結構

    的name和value。在設備中,可描述的信息包括:一、CPU的數量和類別;、內存基地址和大小;三、總線和橋;四、外設連接;五、中斷控制器和中斷使用情況;六、GPIO控制器和GPIO使用情況;七
    發表于 01-07 09:16

    OpenAI推出ChatGPT搜索功能

    近日,OpenAI再次邁出了重要的一步,為其廣受好評的ChatGPT平臺添加了一項全新的搜索功能。 據悉,這項被命名為“ChatGPT搜索”的新功能,將為用戶帶來前所未有的搜索體驗。以往,當用戶需要
    的頭像 發表于 11-04 10:34 ?465次閱讀

    谷歌取消“站點鏈接搜索框”,適應新搜索需求

    近日,谷歌發布了一則通知,決定取消搜索結果中的“站點鏈接搜索框”。這一功能已經陪伴了用戶十多年,它允許用戶在特定網站上進行更深入的搜索,為許多網民提供了便利。然而,隨著時代的變遷和技術的進步,這一
    的頭像 發表于 10-23 11:20 ?443次閱讀

    什么是默克爾(Merkle Tree)?如何計算默克爾根?

    01 默克爾的概念 默克爾(Merkle Tree)是一種特殊的二叉樹,它的每個節點都存儲了一個數據塊的哈希值。哈希值是一種可以將任意長度的數據轉換為固定長度的字符串的算法,它具有唯一性和不可
    的頭像 發表于 09-30 18:22 ?1373次閱讀
    什么是默克爾<b class='flag-5'>樹</b>(Merkle Tree)?如何計算默克爾根?

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

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

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

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

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

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

    原理圖設計里兩顆重要的(國產EDA)

    原理圖里面兩顆重要的,那就是元件和網絡,作為EDA工具中的重要視圖和概念,雖然看似枯燥,但它們扮演著非常重要的角色,它們為電路圖的層次化結構提供了有力支撐。想象一個大型的電路設計項目,就像一個
    的頭像 發表于 05-29 17:47 ?887次閱讀
    原理圖設計里兩顆重要的<b class='flag-5'>樹</b>(國產EDA)

    微軟推出Edge搜索欄,提升用戶搜索效率

    據4月19日消息,微軟近期推出Windows 11與Windows 10系統更新,新增Edge搜索欄桌面集成功能。官方表示,此舉旨在為用戶提供更便捷的搜索體驗,無需開啟瀏覽器即可獲得所需信息,從而提升工作效率。
    的頭像 發表于 04-19 14:44 ?787次閱讀
    主站蜘蛛池模板: 国产精品一久久香蕉国产线看 | 国产乱码精品AAAAAAAA | 国产精品久久久久久AV免费不卡 | 末成年美女黄网站色大片连接 | 亚洲精品无码AAAAAA片 | 最新亚洲一区二区三区四区 | 2019午夜75福利不卡片在线 | 亚洲 小说 欧美 激情 另类 | 97午夜理论片影院在线播放 | 亚洲一卡久久4卡5卡6卡7卡 | 99re8热视频这在线视频 | 欧美国产一区二区三区激情无套 | 男女边吃奶边做边爱视频 | 在线免费福利 | 国产69精品久久久久无码麻豆 | 精品无码久久久久久动漫 | 亚洲精品无码国产爽快A片百度 | 欧美成人免费一区二区三区不卡 | 久久久精品久久久久三级 | 国模丽丽啪啪一区二区 | 国产 在线 亚洲 欧美 动漫 | 青草在线在线d青草在线 | 亚洲国产精品久久精品成人网站 | 中文字幕久精品视频在线观看 | 性色欲情网站IWWW | 亚洲m男在线中文字幕 | asian极品呦女xx农村 | 九九在线精品亚洲国产 | 亚欧乱亚欧乱色视频 | 男人叼女人 | 久久伊人电影 | 久久超碰色中文字幕 | 999人在线精品播放视频 | 一本道亚洲区免费观看 | 亚洲偷偷自拍免费视频在线 | 小黄鸭YELLOWDUCK7596 | xxx性欧美在线观看 xxx性欧美在线 | 学生无码AV一区二区三区 | 精品亚洲视频在线观看 | 饥渴的新婚女教师 | 亚洲精品久久无码AV片银杏 |