Day 15 二叉树part03

110. 平衡二叉树

class Solution {
    public boolean isBalanced(TreeNode root) {
        if(root == null) return true;
        return isBalanced(root.left) && isBalanced(root.right) 
            && Math.abs(hight(root.left) - hight(root.right)) <= 1;
    }

    public int hight(TreeNode root){
        if(root == null) return 0;
        return Math.max(hight(root.left), hight(root.right)) + 1;
    }
}
# 这种方法时间复杂度更低,避免反复重复计算节点高度
class Solution {
    public boolean isBalanced(TreeNode root) {
        return height(root) >= 0;
    }

    public int height(TreeNode root) { //计算节点高度的同时,标记非平衡二叉树
        if (root == null) {
            return 0;
        }
        int leftHeight = height(root.left);
        int rightHeight = height(root.right);
        
        //判断是非平衡的条件:1. 左/右子树非平衡  2.左&右平衡但两树高度之差大于1
        if (leftHeight == -1 || rightHeight == -1 || Math.abs(leftHeight - rightHeight) > 1) {  
            return -1; //-1代表当前节点为根的树是非平衡的
        } else {
            return Math.max(leftHeight, rightHeight) + 1;
        }
    }
}

257. 二叉树的所有路径

这个题可以帮助理解112. 路径总和,做完这道再去做路经总和理解起来就会简单一些。

class Solution {
    public List<String> binaryTreePaths(TreeNode root) {
        List<String> res = new ArrayList(); //存储所有的路径
        List<Integer> path = new ArrayList();  //存储当前路径上所有节点的val
        getPaths(res, root, path);
        return res;
    }

    public void getPaths(List<String> res, TreeNode cur, List<Integer> path){
        path.add(cur.val);  //将当前节点添加到路径中
        if(cur.left == null && cur.right == null) {  //如果当前节点是叶子节点,则把路径存储到res中
            StringBuilder sb = new StringBuilder();
            for(int i = 0; i < path.size() - 1; i++){
                sb.append(path.get(i)+"->");
            }
            sb.append(path.get(path.size()-1));
            res.add(sb.toString());return;
        }
        if(cur.left != null){   
            getPaths(res, cur.left, path);
            path.remove(path.size()-1);  //此时由于已经修改了path,cur.right需要使用修改前的path,因此进行回溯
        }
        if(cur.right != null){
            getPaths(res, cur.right, path);
            path.remove(path.size() - 1);  //同理,由于会修改path,因此在递归后需要进行对path回溯
        }
    }
}

404. 左叶子之和

这道题用递归做是比较容易的,具体看代码注释。

class Solution {
    int ans;
    public int sumOfLeftLeaves(TreeNode root) {
        ans = 0;
        sumLeft(root, root); //由于root一定不是左叶子节点,所以对于第二个参数,传入一个不是root节点父亲节点任意节点即可
        return ans;
    }
    public void sumLeft(TreeNode child, TreeNode parent){ 
        //sumLeft函数传入两个节点,分别对应当前节点和当前节点父亲节点,因此只需判断当前节点是父亲节点的左子节点且当前节点是叶子节点就把他的val加入结果汇总即可
        if(child == null) return;
        if(parent.left == child && child.left == null && child.right == null){
            ans += child.val;
        }
        sumLeft(child.left, child);
        sumLeft(child.right, child);
    }
}

222. 完全二叉树的节点个数

关于时间复杂度的计算可以看这篇题解。和前面大部分的题一样,想不到这个思路是真的做不出来。我想过有像哈夫曼树那样,但我自己写不出来,力扣的官解就是用了二分查找加位运算来做,我自己是实现不出来。

class Solution {
    public int countNodes(TreeNode root) {
        if(root == null) return 0;
        int leftD = 0, rightD = 0;
        TreeNode left = root, right = root;
        while(left != null){
            leftD++;
            left = left.left;
        }
        while(right != null){
            rightD++;
            right = right.right;
        }
        if(leftD == rightD) return (1 << rightD) - 1;
        else return countNodes(root.left) + countNodes(root.right) + 1;
    }
}
posted @ 2024-07-17 15:24  12点不睡觉还想干啥?  阅读(20)  评论(0)    收藏  举报