110.Balanced Binary Tree从8ms到2ms到1ms

在leetcode上面刷了道题,最开始用时8ms,改进后用时2ms,再改用时1ms,下面记录一下:


题目:

Given a binary tree, determine if it is height-balanced.

For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.

简单地说,对于给定的一棵二叉树,判断它是否是平衡二叉树

8ms解法:
  • 容易想见,如果一棵树是平衡二叉树,那么它的左右子树高度差不超过1
  • 而且,如果一棵树是平衡二叉树,那么它的任一子树也是平衡二叉树

    于是,可以这样做:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public boolean isBalanced(TreeNode root) {
        if (root == null) {
            return true;
        }
        return isBalanced(root.left) && isBalanced(root.right) && depth(root.left) - depth(root.right) >= -1 && depth(root.left) - depth(root.right) <= 1;
    }
    private int depth(TreeNode root) {
        // TODO Auto-generated method stub
        if (root == null) {
            return 0;
        }
        return 1 + (depth(root.left) > depth(root.right) ? depth(root.left) : depth(root.right));
    }
}
2ms解法
  • 在上面的解法中,我们发现了一个问题,每次判断一个子树是否是平衡二叉树的时候,我们都要对它的左右子树求高度,也就是说,如果一个结点在这棵二叉树的k棵子树中出现过,那么要计算以这个结点为根节点的子树的高度k次,显然大大增加了时间开销。
  • 于是我利用了树结点中的value去记录以该结点为根节点的子树的高度,那么,当求一棵子树的高度时,可以先求根结点的左右子树的高度,之后将1+max(左子树高度,右子树高度)作为这棵子树的高度。

代码如下:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public boolean isBalanced(TreeNode root) {
        if (root == null) {
            return true;
        }
        root = getDepth(root);
        return isBalanceCore(root);
    }
    private boolean isBalanceCore(TreeNode root) {
        // TODO Auto-generated method stub
        if (root == null) {
            return true;
        }
        if (root.left == null && root.right == null) {
            return true;
        }
        if (root.left != null && root.right == null) {
            if (root.left.left == null && root.left.right == null) {
                return true;
            }
            return false;
        }
        if (root.left == null && root.right != null) {
            if (root.right.left == null && root.right.right == null) {
                return true;
            }
            return false;
        }
        return isBalanceCore(root.left) && isBalanceCore(root.right) && root.left.val - root.right.val >= -1 && root.left.val - root.right.val <= 1;
    }
    private TreeNode getDepth(TreeNode root) {
        // TODO Auto-generated method stub
        if (root.left == null && root.right == null) {
            root.val = 1;
        }else if (root.left != null && root.right == null) {
            root.left = getDepth(root.left);
            root.val = 1 + root.left.val;
        }else if (root.left == null && root.right != null) {
            root.right = getDepth(root.right);
            root.val = 1 + root.right.val;
        }else {
            root.left = getDepth(root.left);
            root.right = getDepth(root.right);
            root.val = 1 + (root.left.val > root.right.val ? root.left.val : root.right.val);
        }
        return root;
    }
}
1ms解法

其实原本这篇博客的题目是从8ms到2ms,就在刚刚写到2ms解法的时候,突然想起来,反正我都要计算树中每个结点为根结点的子树的高度,那么为什么不在计算高度的时候顺便判断一下是不是平衡二叉树呢?

  • 这里我设置了一个全局变量isBalance并初始化为true,每次求完一个结点的value,我都判断一下以它为根的子树是否是平衡二叉树,如果不是,那么修改isBalance的值为false。这样,在对树中每个结点求value之后,就已经知道这棵树是否是平衡二叉树了

代码如下:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    boolean isBalance = true;
    public boolean isBalanced(TreeNode root) {
        if (root == null) {
            return true;
        }
        root = getDepth(root);
        return isBalance;
    }
    private TreeNode getDepth(TreeNode root) {
        // TODO Auto-generated method stub
        if (root.left == null && root.right == null) {
            root.val = 1;
        }else if (root.left != null && root.right == null) {
            root.left = getDepth(root.left);
            root.val = 1 + root.left.val;
            if (root.left.val > 1) {
                isBalance = false;
            }
        }else if (root.left == null && root.right != null) {
            root.right = getDepth(root.right);
            root.val = 1 + root.right.val;
            if (root.right.val > 1) {
                isBalance = false;
            }
        }else {
            root.left = getDepth(root.left);
            root.right = getDepth(root.right);
            root.val = 1 + (root.left.val > root.right.val ? root.left.val : root.right.val);
            if (root.left.val - root.right.val > 1 || root.left.val - root.right.val < -1) {
                isBalance = false;
            }
        }
        return root;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值