在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

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

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

3天內(nèi)不再提示

如何才能夠翻轉(zhuǎn)二叉樹

新材料在線 ? 來源:代碼隨想錄 ? 作者:程序員Carl ? 2021-09-01 11:45 ? 次閱讀

這道題目是非常經(jīng)典的題目,也是比較簡單的題目(至少一看就會)。

但正是因為這道題太簡單,一看就會,一些同學都沒有抓住起本質(zhì),稀里糊涂的就把這道題目過了。

如果做過這道題的同學也建議認真看完,相信一定有所收獲!

226.翻轉(zhuǎn)二叉樹題目地址:https://leetcode-cn.com/problems/invert-binary-tree/

翻轉(zhuǎn)一棵二叉樹。

這道題目背后有一個讓程序員心酸的故事,聽說 Homebrew的作者Max Howell,就是因為沒在白板上寫出翻轉(zhuǎn)二叉樹,最后被Google拒絕了。(真假不做判斷,權(quán)當一個樂子哈)

思路我們之前介紹的都是各種方式遍歷二叉樹,這次要翻轉(zhuǎn)了,感覺還是有點懵逼。

這得怎么翻轉(zhuǎn)呢?

如果要從整個樹來看,翻轉(zhuǎn)還真的挺復雜,整個樹以中間分割線進行翻轉(zhuǎn),如圖:

可以發(fā)現(xiàn)想要翻轉(zhuǎn)它,其實就把每一個節(jié)點的左右孩子交換一下就可以了。

關(guān)鍵在于遍歷順序,前中后序應該選哪一種遍歷順序?(一些同學這道題都過了,但是不知道自己用的是什么順序)

遍歷的過程中去翻轉(zhuǎn)每一個節(jié)點的左右孩子就可以達到整體翻轉(zhuǎn)的效果。

注意只要把每一個節(jié)點的左右孩子翻轉(zhuǎn)一下,就可以達到整體翻轉(zhuǎn)的效果

這道題目使用前序遍歷和后序遍歷都可以,唯獨中序遍歷不行,因為中序遍歷會把某些節(jié)點的左右孩子翻轉(zhuǎn)了兩次!建議拿紙畫一畫,就理解了

那么層序遍歷可以不可以呢?依然可以的!只要把每一個節(jié)點的左右孩子翻轉(zhuǎn)一下的遍歷方式都是可以的!

遞歸法對于二叉樹的遞歸法的前中后序遍歷,已經(jīng)在二叉樹:前中后序遞歸遍歷詳細講解了。

我們下文以前序遍歷為例,通過動畫來看一下翻轉(zhuǎn)的過程:

我們來看一下遞歸三部曲:

確定遞歸函數(shù)的參數(shù)和返回值

參數(shù)就是要傳入節(jié)點的指針,不需要其他參數(shù)了,通常此時定下來主要參數(shù),如果在寫遞歸的邏輯中發(fā)現(xiàn)還需要其他參數(shù)的時候,隨時補充。

返回值的話其實也不需要,但是題目中給出的要返回root節(jié)點的指針,可以直接使用題目定義好的函數(shù),所以就函數(shù)的返回類型為TreeNode*。

TreeNode* invertTree(TreeNode* root)

確定終止條件

當前節(jié)點為空的時候,就返回

if (root == NULL) return root;

確定單層遞歸的邏輯

因為是先前序遍歷,所以先進行交換左右孩子節(jié)點,然后反轉(zhuǎn)左子樹,反轉(zhuǎn)右子樹。

swap(root-》left, root-》right);

invertTree(root-》left);

invertTree(root-》right);

基于這遞歸三步法,代碼基本寫完,C++代碼如下:

class Solution {public

TreeNode* invertTree(TreeNode* root) {

if (root == NULL) return root;

swap(root-》left, root-》right); // 中

invertTree(root-》left); // 左

invertTree(root-》right); // 右

return root;

}

};

迭代法深度優(yōu)先遍歷二叉樹:聽說遞歸能做的,棧也能做!中給出了前中后序迭代方式的寫法,所以本地可以很輕松的切出如下迭代法的代碼:

C++代碼迭代法(前序遍歷)

class Solution {public:

TreeNode* invertTree(TreeNode* root) {

if (root == NULL) return root;

stack《TreeNode*》 st;

st.push(root);

while(!st.empty()) {

TreeNode* node = st.top(); // 中

st.pop();

swap(node-》left, node-》right);

if(node-》right) st.push(node-》right); // 右

if(node-》left) st.push(node-》left); // 左

}

return root;

}

};

如果這個代碼看不懂的話可以在回顧一下二叉樹:聽說遞歸能做的,棧也能做!。

我們在二叉樹:前中后序迭代方式的統(tǒng)一寫法中介紹了統(tǒng)一的寫法,所以,本題也只需將文中的代碼少做修改便可。

C++代碼如下迭代法(前序遍歷)

class Solution {public:

TreeNode* invertTree(TreeNode* root) {

stack《TreeNode*》 st;

if (root != NULL) st.push(root);

while (!st.empty()) {

TreeNode* node = st.top();

if (node != NULL) {

st.pop();

if (node-》right) st.push(node-》right); // 右

if (node-》left) st.push(node-》left); // 左

st.push(node); // 中

st.push(NULL);

} else {

st.pop();

node = st.top();

st.pop();

swap(node-》left, node-》right); // 節(jié)點處理邏輯

}

}

return root;

}

};

如果上面這個代碼看不懂,回顧一下文章二叉樹:前中后序迭代方式的統(tǒng)一寫法。

廣度優(yōu)先遍歷也就是層序遍歷,層數(shù)遍歷也是可以翻轉(zhuǎn)這棵樹的,因為層序遍歷也可以把每個節(jié)點的左右孩子都翻轉(zhuǎn)一遍,代碼如下:

class Solution {public:

TreeNode* invertTree(TreeNode* root) {

queue《TreeNode*》 que;

if (root != NULL) que.push(root);

while (!que.empty()) {

int size = que.size();

for (int i = 0; i 《 size; i++) {

TreeNode* node = que.front();

que.pop();

swap(node-》left, node-》right); // 節(jié)點處理

if (node-》left) que.push(node-》left);

if (node-》right) que.push(node-》right);

}

}

return root;

}

};

如果對以上代碼不理解,或者不清楚二叉樹的層序遍歷,可以看這篇二叉樹:層序遍歷登場!

總結(jié)針對二叉樹的問題,解題之前一定要想清楚究竟是前中后序遍歷,還是層序遍歷。

二叉樹解題的大忌就是自己稀里糊涂的過了(因為這道題相對簡單),但是也不知道自己是怎么遍歷的。

這也是造成了二叉樹的題目“一看就會,一寫就廢”的原因。

針對翻轉(zhuǎn)二叉樹,我給出了一種遞歸,三種迭代(兩種模擬深度優(yōu)先遍歷,一種層序遍歷)的寫法,都是之前我們講過的寫法,融匯貫通一下而已。

大家一定也有自己的解法,但一定要成方法論,這樣才能通用,才能舉一反三!

其他語言版本Java://DFS遞歸class Solution {

/**

* 前后序遍歷都可以

* 中序不行,因為先左孩子交換孩子,再根交換孩子(做完后,右孩子已經(jīng)變成了原來的左孩子),再右孩子交換孩子(此時其實是對原來的左孩子做交換)

*/

public TreeNode invertTree(TreeNode root) {

if (root == null) {

return null;

}

invertTree(root.left);

invertTree(root.right);

swapChildren(root);

return root;

}

private void swapChildren(TreeNode root) {

TreeNode tmp = root.left;

root.left = root.right;

root.right = tmp;

}

}

//BFSclass Solution {

public TreeNode invertTree(TreeNode root) {

if (root == null) {return null;}

ArrayDeque《TreeNode》 deque = new ArrayDeque《》();

deque.offer(root);

while (!deque.isEmpty()) {

int size = deque.size();

while (size-- 》 0) {

TreeNode node = deque.poll();

swap(node);

if (node.left != null) {deque.offer(node.left);}

if (node.right != null) {deque.offer(node.right);}

}

}

return root;

}

public void swap(TreeNode root) {

TreeNode temp = root.left;

root.left = root.right;

root.right = temp;

}

}

Python遞歸法:前序遍歷:

class Solution:

def invertTree(self, root: TreeNode) -》 TreeNode:

if not root:

return None

root.left, root.right = root.right, root.left #中

self.invertTree(root.left) #左

self.invertTree(root.right) #右

return root

迭代法:深度優(yōu)先遍歷(前序遍歷):

class Solution:

def invertTree(self, root: TreeNode) -》 TreeNode:

if not root:

return root

st = []

st.append(root)

while st:

node = st.pop()

node.left, node.right = node.right, node.left #中

if node.right:

st.append(node.right) #右

if node.left:

st.append(node.left) #左

return root

迭代法:廣度優(yōu)先遍歷(層序遍歷):

import collections

class Solution:

def invertTree(self, root: TreeNode) -》 TreeNode:

queue = collections.deque() #使用deque()

if root:

queue.append(root)

while queue:

size = len(queue)

for i in range(size):

node = queue.popleft()

node.left, node.right = node.right, node.left #節(jié)點處理

if node.left:

queue.append(node.left)

if node.right:

queue.append(node.right)

return root

責任編輯:haq

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

    關(guān)注

    22

    文章

    2114

    瀏覽量

    73858
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4827

    瀏覽量

    69054
  • 二叉樹
    +關(guān)注

    關(guān)注

    0

    文章

    74

    瀏覽量

    12376

原文標題:你真的會翻轉(zhuǎn)二叉樹么?

文章出處:【微信號:xincailiaozaixian,微信公眾號:新材料在線】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    科技在物聯(lián)網(wǎng)方面

    的發(fā)展,對傳感器的需求不斷增加且要求越來越高,宇科技通過與傳感器公司的合作,不斷優(yōu)化和拓展傳感器技術(shù)在其機器人產(chǎn)品中的應用,使機器人能夠更好地適應各種物聯(lián)網(wǎng)場景下的感知需求,如在智能家居場景中感知房間
    發(fā)表于 02-04 06:48

    ADS1259初始化程序必須執(zhí)行兩次才能夠初始化成功,為什么?

    最近在調(diào)試ADS1259這個片子,發(fā)現(xiàn)初始化程序必須執(zhí)行兩次才能夠初始化成功,然后讀出來的CONFIG0寄存器的最高位是“0”(官方文檔上是“1”),不知道是什么原因,求TI工程師解答呀!
    發(fā)表于 01-10 12:41

    飛凌嵌入式ElfBoard ELF 1板卡-初識設備之設備組成和結(jié)構(gòu)

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

    ADS1298采用怎樣的平均方法才能夠將高采樣率的數(shù)據(jù)平均成低采樣率后,相應的把噪聲降下來?

    是非常小的。這也符合datasheet上8.1 Noise Measurements的描述; 我們現(xiàn)在的問題是:采用怎樣的平均方法才能夠將高采樣率的數(shù)據(jù)平均成低采樣率后,相應的把噪聲降下來?
    發(fā)表于 01-07 06:53

    先進封裝中的翻轉(zhuǎn)芯片技術(shù)概述

    引言 翻轉(zhuǎn)芯片技術(shù)已成為半導體行業(yè)中不可或缺的封裝方法,在性能、尺寸減小和功能增加方面具有優(yōu)勢。本文概述翻轉(zhuǎn)芯片技術(shù),包括晶圓凸塊制作工藝、組裝方法和進展。 翻轉(zhuǎn)芯片技術(shù)簡介 翻轉(zhuǎn)芯片
    的頭像 發(fā)表于 11-27 10:58 ?610次閱讀
    先進封裝中的<b class='flag-5'>翻轉(zhuǎn)</b>芯片技術(shù)概述

    AIC3254要怎么做才能夠做到反饋抑制呢?

    設計,連編譯都無法通過。各位大俠,到底怎么辦呢,期待各位大俠的幫助,謝謝了,萬分感謝。AIC3254要怎么做,才能夠做到反饋抑制呢?
    發(fā)表于 11-08 07:49

    鐳神智能機器人三向式3D SLAM無人叉車:重塑高位堆垛與窄通道倉儲新境界

    °旋轉(zhuǎn)左右取的卓越性能,解鎖更多高位密集倉儲場景應用。5m高位堆垛,挑戰(zhàn)倉儲新高度LXK12-B無人叉車憑借其強大的舉升能力,能夠輕松實現(xiàn)高達5m的高位堆垛,極大地
    的頭像 發(fā)表于 10-26 08:03 ?205次閱讀
    鐳神智能機器人三向<b class='flag-5'>叉</b>式3D SLAM無人叉車:重塑高位堆垛與窄通道倉儲新境界

    ppc3安裝后只有第一次打開才正常,關(guān)閉ppc3后第次打開,無論如何就進不去界面了,為什么?

    我上個月申請了ppc3的下載。現(xiàn)在安裝后只有第一次打開才正常,才能夠正常看到界面并登陸。如果關(guān)閉ppc3后第次打開,無論如何就進不去界面了。除非再重新安裝一遍才能打開。 下面就是這個進不去的界面:
    發(fā)表于 10-22 07:23

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

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

    怎么才能夠將正弦波的直流分量取出?

    請教怎么才能夠將正弦波的直流分量取出,(我用低通濾波之后噪聲很大)
    發(fā)表于 09-19 06:13

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

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

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

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

    Endpoint端點如何做才能夠達到不需要PC端手動IN就將數(shù)據(jù)往上推送?

    您好,我想問一下Endpoint端點如何做才能夠達到不需要PC端手動IN就將數(shù)據(jù)往上推送? 使用的是FX3芯片,其中我發(fā)現(xiàn)在鼠標HID范例中,它就是不需要電腦IN,只要在某一個GPIO口觸發(fā)之后
    發(fā)表于 05-27 08:29

    tle9879 hall電機啟動需要用手撥動一下才能轉(zhuǎn)動怎么解決?

    才能夠正常啟動運轉(zhuǎn),否則就不轉(zhuǎn)動。 已經(jīng)試著調(diào)試過啟動占空比,給定的速度,以及 pid參數(shù),都不管用。 問下能夠得到指點一下,感謝!
    發(fā)表于 03-28 07:58

    求助,關(guān)于STM32F103翻轉(zhuǎn)使用的疑問求解

    通用定時器輸出比較TIM2,F(xiàn)103.根據(jù)參考手冊輸出比較是CNT與CRR比較。CNT=CRR翻轉(zhuǎn)。程序設置:定時器時鐘72M,預分頻系數(shù)71,ARR=999.CRR為499.實際仿真波形和示波器輸出波形1ms翻轉(zhuǎn)一次。為什么不是0.5ms
    發(fā)表于 03-11 07:47
    主站蜘蛛池模板: 亚洲成a人片在线观看中 | 国内一级特黄女人精品片 | 国产日韩精品欧美一区色 | 亚洲乱码一二三四区 | 国产亚洲美女 | 亚洲91精品| 日本免费网站观看 | 69xxxx欧美老师 | 又粗又爽又色男女乱淫播放男女 | 天天操天天透 | 亚洲精品久久久久午夜三 | 免费深夜视频 | 视频在线观看网站 | 一级特黄特黄的大片免费 | 爱爱免费 | 四虎影视免费观看 | 777影院| 一级毛片不卡 | 亚州一级毛片在线 | 韩国视频在线播放 | 天天躁夜夜躁狠狠躁2024 | 久久毛片视频 | 草草影院www色极品欧美 | 亚洲综合成人在线 | 五月天丁香激情 | 成人a网 | 午夜激情福利 | 四虎影院美女 | 狠狠色噜噜狠狠狠狠2018 | 日日做夜夜做 | 性试验k8经典 | 97精品伊人久久大香线蕉 | 日本三级日本三级人妇三级四 | 日韩一级在线播放免费观看 | 丁香月婷婷 | a天堂影院| 5555kkkk香蕉在线观看 | 国产一二三区在线 | 天天操夜操 | 综合网自拍 | tube69日本老师 |