代码随想录算法训练营Day15

完全二叉树结点的数量

  1. 后序遍历套模板,时间复杂度为O(n)
class Solution {  
    public int countNodes(TreeNode root) {  
        if(root == null){  
            return 0;  
        }  
        int l = countNodes(root.left);  
        int r = countNodes(root.right);  
        int result = l+r+1;  
        return result;  
    }  
}
  1. 根据完全二叉树的特点简化上述代码,如果一侧是满二叉树,直接用2^深度-1算得满子树的节点数(如何判断是满二叉树?向左遍历得到的深度和向右遍历得到的深度相等)
class Solution {  
    public int countNodes(TreeNode root) {  
        if (root == null) {  
            return 0;  
        }  
        TreeNode left = root.left;  
        TreeNode right = root.right;  
        int ldepth = 1;  
        int rdepth = 1;  
        while (left != null) {  
            left = left.left;  
            ldepth++;  
        }  
        while (right != null) {  
            right = right.right;  
            rdepth++;  
        }  
        if (ldepth == rdepth) {  
            return (int) Math.pow(2, ldepth) - 1;//满二叉树的公式  
        }  
        int ld = countNodes(root.left);  
        int rd = countNodes(root.right);  
        return ld + rd + 1;  
    }  
}

平衡二叉树

最大高度的应用,注意跳出递归的条件

class Solution {  
    public boolean isBalanced(TreeNode root) {  
        if(root == null){  
            return true;  
        }  
        if(Math.abs(depth(root.left)-depth(root.right))>1){  
            return false;  
        }  
        boolean l = isBalanced(root.left);  
        boolean r = isBalanced(root.right);  
        return l&&r;  
    }  
    public int depth(TreeNode root){  
        if(root == null){  
            return 0;  
        }  
        int ld = depth(root.left);  
        int rd = depth(root.right);  
        return Math.max(ld,rd)+1;  //这里混了,求最大高度不是求节点数量!
    }  
}

二叉树的所有路径

回溯的思想,在遍历完左子树之后,将左子节点弹出,再遍历右子节点

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 sb = new StringBuilder();  
            for (int i = 0; i < paths.size() - 1; i++) {//加->的  
                sb.append(paths.get(i)).append("->");  
            }  
            sb.append(paths.get(paths.size() - 1));//不加->的  
            res.add(sb.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);// 回溯  
        }  
    }  
}

所有左叶子结点的和

下面代码求得是所有叶子结点的和

class Solution {  
    public int sumOfLeaves(TreeNode root) {  
        if (root == null) {  
            return 0;  
        } else if (root.left == null && root.right == null) {  
            return root.val; // 当前节点是叶子节点,返回其值  
        }  
        // 递归计算左右子树的叶子节点和  
        int l = sumOfLeaves(root.left);  
        int r = sumOfLeaves(root.right);  
        return l + r;  
    }  
}

下面代码是求所有左叶子结点的和

class Solution {  
    public int sumOfLeftLeaves(TreeNode root) {  
        if(root == null){  
            return 0;  
        }  
        int l = sumOfLeftLeaves(root.left);  
        int r = sumOfLeftLeaves(root.right);  
        int mid = 0;  
        if(root.left != null && root.left.right == null && root.left.left == null){  
            mid = root.left.val;  
        }  
        return l+r+mid;  
    }  
}
posted @ 2025-04-09 08:55  Anson_502  阅读(11)  评论(0)    收藏  举报