Day17~110.平衡二叉树、257. 二叉树的所有路径、404.左叶子之和

87 阅读2分钟

摘要

本文主要介绍了LeetCode二叉树的几个题目,包括110.平衡二叉树、257. 二叉树的所有路径、404.左叶子之和。

1、110.平衡二叉树

1.1 解法一

  • 迭代遍历
  • 判断当前节点是否是高度平衡的二叉树, 计算左右子树的高度,判断高度差的绝对值是否超过 1
  • 然后继续判断当前节点的左子树或右子树是否是高度平衡的二叉树
    public boolean isBalanced(TreeNode root) {
        if(root == null) {
            return true;
        }
​
        boolean result = Math.abs(getHeight(root.left) - getHeight(root.right)) <= 1;
        return result && isBalanced(root.left) && isBalanced(root.right);
    }
​
    public int getHeight(TreeNode root) {
        if(root == null) {
            return 0;
        }
​
        return Math.max(getHeight(root.left), getHeight(root.right)) + 1;
    }

1.2 解法二

  • 迭代遍历
  • 计算左右子树的高度,并在递归过程中判断是否是高度平衡的二叉树
  • 如果左右两个子树的高度差的绝对值超过1,则返回-1,如果左右子树的高度是-1,继续向上返回-1
  • 否则返回二叉树的高度
    public boolean isBalanced(TreeNode root) {
        return isHeight(root) != -1;
    }
​
    public int isHeight(TreeNode root) {
        if(root == null) {
            return 0;
        }
        
        // 递归过程中判断是否是高度平衡的二叉树
        int leftHeight = isHeight(root.left);
        if(leftHeight == -1) {
            return -1;
        }
        int rightHeight = isHeight(root.right);
        if(rightHeight == -1) {
            return -1;
        }
        boolean result = Math.abs(leftHeight - rightHeight) <= 1;
        if(!result) {
            return -1;
        }
​
        return Math.max(leftHeight, rightHeight) + 1;
    }

2、257. 二叉树的所有路径

2.1 思路

  • 递归+回溯
  • 递归遍历,将当前节点的值加入到LinkedList中,遍历左右子树,遍历结束从LinkedList删除值
  • 如果当前节点为空,直接返回;如果当前节点是叶子节点,将LinkedList加入到返回结果中
  • 直至遍历完成

1、如果拼接字符串,如"1->2->5"?

定义LinkedList保存元素,遍历到叶子节点时,将LinkedList转换ArrayList,fori 循环遍历拼接字符串

2、可以在叶子节点的判断条件中退出递归?

其实也可以,但是在退出递归调用之前,LinkedList也需要删除元素(removeLast())

2.2 代码

    public List<String> binaryTreePaths(TreeNode root) {
        List<String> result = new ArrayList<>();
        LinkedList<Integer> linkedList = new LinkedList<>();
​
        doBinaryTreePaths(root, result, linkedList);
        return result;
    }
​
    public void doBinaryTreePaths(TreeNode root, List<String> result, LinkedList<Integer> linkedList) {
        if(root == null) {
            return;
        }
​
        linkedList.add(root.val);
        if(root.left == null &&  root.right == null) {
            StringBuilder builder = new StringBuilder();
            List<Integer> list = new ArrayList(linkedList);
            for(int i=0; i<list.size(); i++) {
                builder.append(list.get(i));
                if(i != list.size()-1) {
                   builder.append("->"); 
                }
            }
            result.add(builder.toString());
        }
​
        doBinaryTreePaths(root.left, result, linkedList);
        doBinaryTreePaths(root.right, result, linkedList);
        linkedList.removeLast();
    }

3、404.左叶子之和

3.1 思路

  • 递归遍历
  • 如果当前节点为空,返回0
  • 如果当前节点是左节点并且它的左右节点都为空,则返回该节点的值
  • 继续遍历左右子树

3.2 代码

    public int sumOfLeftLeaves(TreeNode root) {
        return doSumOfLeftLeaves(root, false);
    }
​
    public int doSumOfLeftLeaves(TreeNode root, boolean isLeft) {
        if(root == null) {
            return 0;
        }
​
        if(isLeft && root.left == null && root.right == null) {
            return root.val;
        }
​
        return doSumOfLeftLeaves(root.left, true) + doSumOfLeftLeaves(root.right, false);
    }

参考资料

代码随想录-平衡二叉树

代码随想录-二叉树的所有路径

代码随想录-左叶子之和