代碼隨想錄算法訓練營第15天 | 110.平衡二叉樹馅扣、257. 二叉樹的所有路徑、404.左葉子之和着降、222.完全二叉樹的節(jié)點個數(shù)

110.平衡二叉樹 (優(yōu)先掌握遞歸)

題目鏈接/文章講解/視頻講解
再一次涉及到差油,什么是高度,什么是深度鹊碍,可以鞏固一下厌殉。

思路

  • 任何節(jié)點的左右子樹高度差小于等于1則是平衡二叉樹
  • 高度和深度:高度:到葉子節(jié)點的距離;深度:到根節(jié)點的距離侈咕。這道題求高度公罕,就是后序遍歷。

偽代碼

//定義遞歸函數(shù)耀销,參數(shù)和返回值
private int getHeight(TreeNode root){
    //終止條件  空節(jié)點高度為0
    if(node == null) return 0;  
    //發(fā)現(xiàn)任何一個節(jié)點不符合平衡二叉樹的定義楼眷,直接返回-1
    //采用后序遍歷  左右中
    int leftHeight = getHeight(root.left);  //左子樹高度
    if(leftHeight == -1)  return -1;  //左子樹高度==-1不符合平衡二叉樹
    int rightHeight = getHeight(root.right);  //右子樹高度
    if(rightHeight == -1) return -1;
    int result;
    //  一定要把中寫在左右子樹的后面,才能獲取左右的情況返回給父節(jié)點
    if(Math.abs(leftHeight - rightHeight)  > 1){  //相減絕對值大于1  
        result = -1;
    }else{
      //  左右子樹高度取最大值再加一
        result = Math.max(leftHeight, rightHeight) + 1;
    }
    return result;
}
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public boolean isBalanced(TreeNode root) {
        return getHeight(root) != -1;  //為什么這里要這么寫
    }
    private int getHeight(TreeNode root){
        if(root == null) return 0;
        int leftHeight = getHeight(root.left);
        if(leftHeight == -1) return -1;
        int rightHeight = getHeight(root.right); 
        if(rightHeight == -1) return -1;
        return Math.abs(leftHeight - rightHeight) > 1 ? -1 : (Math.max(leftHeight, rightHeight) + 1);
    }
}

257. 二叉樹的所有路徑 (優(yōu)先掌握遞歸)

題目鏈接/文章講解/視頻講解

思路

  • 返回從根節(jié)點到葉子節(jié)點的所有路徑
  • 使用前序遍歷:這樣才能讓父節(jié)點指向孩子節(jié)點熊尉,才能把路徑輸出出來
  • 只要有遞歸就一定有回溯
    • 為什么會有回收的過程:一個容器來收集路徑罐柳,怎么把一條路徑收集完后,把子節(jié)點彈出去狰住,重新回到根節(jié)點記錄新路徑呢张吉?所以有回溯。

偽代碼

//1. 定義函數(shù)催植,定義參數(shù)和返回值
// root 根節(jié)點肮蛹; paths 記錄單條路徑的數(shù)組勺择;res  記錄最后結果,也是返回值
 private void traversal(TreeNode node, List<Integer> paths, List<String> res) {
//3. 前序遍歷伦忠,中節(jié)點省核,因為遍歷到葉子節(jié)點就結束了,所以要把葉子節(jié)點放進入才中止
paths.add(node.val);
//2. 確定終止條件:遍歷到葉子節(jié)點
if(node.left == null && node.right == null){
    // 要把paths轉化成String然后元素之間加上"->"昆码,代碼略
    StringBuilder sb = new StringBuilder();// StringBuilder用來拼接字符串
    ……
    res.add(sb.toString())
    return;
  }
//向左遞歸
if(node != null){
    traversal(root.left, paths, res);
    paths.remove(paths.size() - 1);// 回溯气忠,可以隱藏在參數(shù)中
}
//向右遞歸
if(node != null){
    traversal(root.right, paths, res);
    paths.remove(paths.size() - 1);// 回溯
}

    
}
}

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<String> binaryTreePaths(TreeNode root) {
        List<String> res = new ArrayList<>();// 存最終的結果
        if (root == null) {
            return res;
        }
        List<Integer> paths = new ArrayList<>();// 作為結果中的路徑
        traversal(root, paths, res);
        return res;
        
    }

    private void traversal(TreeNode root, List<Integer> paths, List<String> res){
        paths.add(root.val);
        if(root.left == null && root.right == null){
            StringBuilder s = new StringBuilder();
            for(int i = 0; i < paths.size()-1; i++){
                s.append(paths.get(i)).append("->");
            }
            s.append(paths.get(paths.size() - 1));
            res.add(s.toString());
            return;
        }
        if(root.left != null){
            traversal(root.left, paths, res);
            paths.remove(paths.size()-1);
        }
        if(root.right != null){
            traversal(root.right, paths, res);
            paths.remove(paths.size()-1);
        }
    }
}

404.左葉子之和 (優(yōu)先掌握遞歸)

題目鏈接/文章講解/視頻講解
其實本題有點文字游戲,搞清楚什么是左葉子赋咽,剩下的就是二叉樹的基本操作旧噪。

思路

  • 左葉子節(jié)點的定義:一定是葉子節(jié)點(子節(jié)點為空);一定是父節(jié)點的左孩子冬耿。
  • 和之前二叉樹題目的區(qū)別:無法判斷葉子節(jié)點是不是父節(jié)點的左孩子舌菜,所以判斷條件是:一個節(jié)點的左孩子不為空,同時左孩子的左右孩子都為空亦镶。
  • 使用后序遍歷日月,因為要一層一層向上返回

偽代碼

public int sumOfLeftLeaves(TreeNode root) {
    //終止條件
    if(root == null) return 0;
    if(root.left == null && root.right == null) return 0; // 不寫也行,只是遞歸多了一層
    //單層遞歸的邏輯
    
    int leftNum = sumOfLeftLeaves(root.left);
    //左孩子不為空缤骨,同時左孩子為葉子節(jié)點
    if(root.left != null && root.left.left != null && root.right.right != null){
        leftNum = root.left.val;
    }
    int rightNum = sumOfLeftLeaves(root.right);
    int sum = leftNum + rightNum
    return sum; 
}
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int sumOfLeftLeaves(TreeNode root) {
        if (root == null) return 0;
        if (root.left == null && root.right == null) return 0;

        int leftValue = sumOfLeftLeaves(root.left);    // 左
        if (root.left != null && root.left.left == null && root.left.right == null) { // 左子樹就是一個左葉子的情況
            leftValue = root.left.val;
        }
        int rightValue = sumOfLeftLeaves(root.right);  // 右

        int sum = leftValue + rightValue;               // 中
        return sum;
    }
}

222.完全二叉樹的節(jié)點個數(shù)(優(yōu)先掌握遞歸)

題目鏈接/文章講解/視頻講解
需要了解爱咬,普通二叉樹 怎么求,完全二叉樹又怎么求

思路

  • 如果是普通的二叉樹绊起,就是遍歷節(jié)點

后序遍歷

class Solution {
    // 通用遞歸解法
    public int countNodes(TreeNode root) {
        if(root == null) {
            return 0;
        }
        return countNodes(root.left) + countNodes(root.right) + 1;
    }
}
  • 利用完全二叉樹的特性的寫法
  • 完全二叉樹的定義:除了底層節(jié)點每一層都是滿的精拟,底層節(jié)點都集中在該層最左邊
  • 只要知道深度,節(jié)點數(shù)量就是2的深度次方 -1
  • 所以就是左子樹的數(shù)量+右子樹的數(shù)量+1
  • 如果是滿二叉樹虱歪,往左右兩邊遍歷的深度相等蜂绎;如果子樹不相等則不是滿二叉樹,那么就繼續(xù)向下遞歸笋鄙,一定可以遇到符合滿足條件的節(jié)點
public int countNodes(TreeNode root) {
//終止條件
        if (root == null) return 0;
        //遇到子樹為滿二叉樹师枣,也要返回結果并終止
        TreeNode left = root.left;
        TreeNode right = root.right;
        int leftDepth = 0, rightDepth = 0; // 這里初始為0是有目的的,為了下面求指數(shù)方便
        while (left != null) {  // 求左子樹深度
            left = left.left;
            leftDepth++;
        }
        while (right != null) { // 求右子樹深度
            right = right.right;
            rightDepth++;
        }
        if (leftDepth == rightDepth) {
            return (2 << leftDepth) - 1; // 注意(2<<1) 相當于2^2萧落,所以leftDepth初始為0
        }
        return countNodes(root.left) + countNodes(root.right) + 1;
    }
}
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末践美,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子找岖,更是在濱河造成了極大的恐慌陨倡,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件许布,死亡現(xiàn)場離奇詭異兴革,居然都是意外死亡,警方通過查閱死者的電腦和手機蜜唾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進店門杂曲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來箕昭,“玉大人,你說我怎么就攤上這事解阅。” “怎么了泌霍?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵货抄,是天一觀的道長。 經(jīng)常有香客問我朱转,道長蟹地,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任藤为,我火速辦了婚禮怪与,結果婚禮上,老公的妹妹穿的比我還像新娘缅疟。我一直安慰自己分别,他們只是感情好,可當我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布存淫。 她就那樣靜靜地躺著耘斩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪桅咆。 梳的紋絲不亂的頭發(fā)上括授,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天,我揣著相機與錄音岩饼,去河邊找鬼荚虚。 笑死,一個胖子當著我的面吹牛籍茧,可吹牛的內(nèi)容都是我干的版述。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼硕糊,長吁一口氣:“原來是場噩夢啊……” “哼院水!你這毒婦竟也來了?” 一聲冷哼從身側響起简十,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤檬某,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后螟蝙,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體恢恼,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年胰默,在試婚紗的時候發(fā)現(xiàn)自己被綠了场斑。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片漓踢。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖漏隐,靈堂內(nèi)的尸體忽然破棺而出喧半,到底是詐尸還是另有隱情,我是刑警寧澤青责,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布挺据,位于F島的核電站,受9級特大地震影響脖隶,放射性物質(zhì)發(fā)生泄漏扁耐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一产阱、第九天 我趴在偏房一處隱蔽的房頂上張望婉称。 院中可真熱鬧,春花似錦构蹬、人聲如沸王暗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瘫筐。三九已至,卻和暖如春铐姚,著一層夾襖步出監(jiān)牢的瞬間策肝,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工隐绵, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留之众,地道東北人。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓依许,卻偏偏與公主長得像棺禾,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子峭跳,可洞房花燭夜當晚...
    茶點故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容