Skip to content

Latest commit

 

History

History
272 lines (238 loc) · 7.59 KB

110.md

File metadata and controls

272 lines (238 loc) · 7.59 KB

平衡二叉树:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。

思路

  • 判断每个节点左右子树的高度差是否小于 1,可从上往下判断,也可从下往上判断
  • 从上往下,如果根节点满足高度差小于 1,继续遍历左右子树节点是否符合条件。
# 节点 1:高度差小于 1,左右子树不一定平衡       
       1
      / \
     2   2
    /     \
   3       3
  /         \
 4           4
  • 从下往上,判断节点左右子树是否为平衡树,通过两者的高度再判断节点是否为平衡树
# 节点 1:左右子树平衡,高度差不一定小于 1
       1
      / \
     2   2
    / \
   3   3
  / \
 4   4

从上往下

  • 标签:从上往下递归
  • 时间复杂度:如果树是平衡二叉树,节点被重复遍历的次数与所在层数对应。
  • 空间复杂度:函数调用栈的高度。函数调用栈的高度等于树的高度。如果树完全倾斜,树有 n 个节点,高度为 n。最差空间复杂度为 O(n)

代码

# Python3
class Solution:
    def isBalanced(self, root: TreeNode) -> bool:
        if root == None:
            return True
        if abs(self.height(root.left) - self.height(root.right)) > 1:
            return False
        else:
            return self.isBalanced(root.left) and self.isBalanced(root.right)
    def height(self, root: TreeNode) -> int:
        if root == None:
            return 0
        if root.left == None and root.right == None:
            return 1
        else:
            return 1 + max(self.height(root.left),self.height(root.right))
// Java
class Solution {
    public boolean isBalanced(TreeNode root) {
        if (root == null) {
            return true;
        }
        if (Math.abs(height(root.left) - height(root.right)) > 1) {
            return false;
        } else {
            return isBalanced(root.left) && isBalanced(root.right);
        }
    }

    public int height(TreeNode root) {
        if (root == null) {
            return 0;
        }
        if (root.left == null && root.right == null) {
            return 1;
        } else {
            return 1 + Math.max(height(root.left),height(root.right));
        }
    }
}

从下往上

  • 同时返回子树是否平衡和子树的高度。也可只返回高度差?
  • 标签:从下往上
  • 时间复杂度:O(n),n 为节点的数量,每个节点只会遍历一次
  • 空间复杂度:O(n),函数调用栈的高度等于树的高度。如果树完全倾斜,树有 n 个节点,高度为 n。最差空间复杂度为 O(n)

代码

# Python3
class Solution:
    def isBalanced(self, root: TreeNode) -> bool:
        return self.isBalancedHelper(root)[0]
    def isBalancedHelper(self, root: TreeNode) -> (bool,int):
        if root == None:
            return True,0
        if root.left == None and root.right == None:
            return True,1
        leftIsBalanced,leftHeight = self.isBalancedHelper(root.left)
        if not leftIsBalanced:
            return False,0
        rightIsBalanced,rightHeight = self.isBalancedHelper(root.right)
        if not rightIsBalanced:
            return False,0
        return abs(leftHeight - rightHeight) <= 1,1 + max(leftHeight,rightHeight)
// Java,使用 List 存放 isBalanced 和 height
class Solution {
    public boolean isBalanced(TreeNode root) {
        return (Boolean)isBalancedHelper(root).get(0);
    }
    public List<Object> isBalancedHelper(TreeNode root) {
        if (root == null) {
            return new ArrayList<Object>(){{add(true);add(0);}};
        }
        if (root.left == null && root.right == null) {
            return new ArrayList<Object>(){{add(true);add(1);}};
        }
        List<Object> leftList = isBalancedHelper(root.left);
        boolean leftIsBalanced = (Boolean)leftList.get(0);
        int leftHeight = (Integer)leftList.get(1);
        if (!leftIsBalanced) {
            return new ArrayList<Object>(){{add(false);add(0);}};
        }
        List<Object> rightList = isBalancedHelper(root.right);
        boolean rightIsBalanced = (Boolean)rightList.get(0);
        int rightHeight = (Integer)rightList.get(1);
        if (!rightIsBalanced) {
            return new ArrayList<Object>(){{add(false);add(0);}};
        }
        return new ArrayList<Object>(){{
            add(Math.abs(leftHeight - rightHeight) <= 1);
            add(1 + Math.max(leftHeight,rightHeight));
        }};
    }
}
// Java,使用对象
class Solution {
    public boolean isBalanced(TreeNode root) {
        return isBalancedHelper(root).isBalanced;
    }
    public TreeInfo isBalancedHelper(TreeNode root) {
        if (root == null) {
            return new TreeInfo(true, 0);
        }
        if (root.left == null && root.right == null) {
            return new TreeInfo(true, 1);
        }
        TreeInfo treeInfoLeft = isBalancedHelper(root.left);
        boolean leftIsBalanced = treeInfoLeft.isBalanced;
        int leftHeight = treeInfoLeft.height;
        if (!leftIsBalanced) {
            return new TreeInfo(false, 0);
        }
        TreeInfo treeInfoRight = isBalancedHelper(root.right);
        boolean rightIsBalanced = treeInfoRight.isBalanced;
        int rightHeight = treeInfoRight.height;
        if (!rightIsBalanced) {
            return new TreeInfo(false, 0);
        }
        boolean isBalanced = Math.abs(leftHeight - rightHeight) <= 1;
        int height = 1 + Math.max(leftHeight,rightHeight);
        return new TreeInfo(isBalanced, height);
    }
}

final class TreeInfo {
    final boolean isBalanced;
    final int height;
    public TreeInfo(boolean isBalanced, int height) {
        this.isBalanced = isBalanced;
        this.height = height;
    }
}

测试用例

    3
   / \
  9  20
    /  \
   15   7
   
[3,9,20,null,null,15,7]
       1
      / \
     2   2
    / \
   3   3
  / \
 4   4
 
[1,2,2,3,3,null,null,4,4]
    1
   / 
  2  
  
[1,2]  
       1
      / \
     2   2
    /     \
   3       3
  /         \
 4           4
 
[1,2,2,3,null,null,3,4,null,null,4]

前期思考

class Solution:
    def isBalanced(self, root: TreeNode) -> bool:
        if root == None:
            return True
        return slef.isBalanced(left) and self.isBalanced(root.right)
                    1       3          2    20
        return abs(height(left,1) - height(right,1)) <= 1
    
    def judge(self, root: TreeNode) -> bool:
        if root.left == None and root.right == None:
            return true
        return judge(root.left)[0] and judge(root.left)[0]
        if abs(self.height(root.left) - self.height(root.right)) <= 1:
            return true
        return False
        return judge(root.left) and judge(root.left)
    def height(root: TreeNode) -> int:
        if root.left == None and root.right == None:
            return 1
        else:
            return 1+max(height(root.left),height(root.right))
  • 如果左子树是平衡树,返回高度,如果不是,结束递归;如果右子树是平衡树,返回高度,如果不是,结束递归。
  • 从上往下比较
    • 1 是
    • 2 不是
  • 从下往上比较,
    • 1 有左右子树,往下
    • 4 是,左右子树高度为 0
    • 3 是,左右子树高度为 1 和 0
    • 2 不是,左右子树高度为 2 和 0,结束