Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

leetcode110:平衡二叉树 #44

Open
sisterAn opened this issue May 18, 2020 · 5 comments
Open

leetcode110:平衡二叉树 #44

sisterAn opened this issue May 18, 2020 · 5 comments

Comments

@sisterAn
Copy link
Owner

sisterAn commented May 18, 2020

给定一个二叉树,判断它是否是高度平衡的二叉树。

本题中,一棵高度平衡二叉树定义为:

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

示例 1:

给定二叉树 [3,9,20,null,null,15,7]

    3
   / \
  9  20
    /  \
   15   7

返回 true

示例 2:

给定二叉树 [1,2,2,3,3,null,null,4,4]

      1
     / \
    2   2
   / \
  3   3
 / \
4   4

返回 false

附赠leetcode地址:leetcode

@plane-hjh
Copy link

plane-hjh commented May 19, 2020

思路:后序遍历,使用递归计算节点的高度

  1. 比较左右子树的深度,若差值大于1 则返回一个标记 -1表示当前子树不平衡

  2. 左右子树有一个不是平衡的,或左右子树差值大于1,则整课树不平衡

  3. 若左右子树平衡,返回当前树的深度(左右子树的深度最大值+1)

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {TreeNode} root
 * @return {boolean}
 */
var isBalanced = function (root) {
  function balanced(node) {
    // 递归的基线条件
    if (!node) return 0;

    // 后序遍历
    const left = balanced(node.left);
    const right = balanced(node.right);

    if (left == -1 || right == -1 || Math.abs(left - right) > 1) return -1;

    // 从底层的0开始,每一层+1之后往外抛
    return Math.max(left, right) + 1;
  }

  return balanced(root) !== -1
};

@luweiCN
Copy link

luweiCN commented May 19, 2020

var treeHeight = function (root) {
  if (root === null) return 0;
  return Math.max(treeHeight(root.left), treeHeight(root.right)) + 1;
};

/**
 * @param {TreeNode} root
 * @return {boolean}
 */
var isBalanced = function (root) {
  if (root === null) return true;
  let leftHeight = treeHeight(root.left);
  let rightHeight = treeHeight(root.right);
  if (Math.abs(leftHeight - rightHeight) > 1) {
    return false;
  } else {
    return isBalanced(root.left) && isBalanced(root.right);
  }
};

@13001920223
Copy link

解题思路

· 定义height方法获取二叉树最大深度

· 获取子树高度,如果差值大于一则不是平衡二叉树返回false

· 递归调用直到遍历完成

var isBalanced = function(root) {
    if (!root) { // 如果没有值直接返回true
        return true
    }
    if (Math.abs(height(root.left) - height(root.right)) > 1) { // 判断差值是否大于1
        return false
    }
    return isBalanced(root.left) && isBalanced(root.right); // 递归调用子树
};
function height(root) { // 获取子树最大深度
    if (!root) {
        return 0
    }
    return Math.max(height(root.left), height(root.right)) + 1;
}

@sisterAn
Copy link
Owner Author

sisterAn commented May 19, 2020

解答一:自顶向下(暴力法)

解题思路: 自顶向下的比较每个节点的左右子树的最大高度差,如果二叉树中每个节点的左右子树最大高度差小于等于 1 ,即每个子树都平衡时,此时二叉树才是平衡二叉树

代码实现:

const isBalanced = function (root) {
  if(!root) return true
  return Math.abs(depth(root.left) - depth(root.right)) <= 1
        && isBalanced(root.left)
        && isBalanced(root.right)
}
const depth = function (node) {
    if(!node) return -1
    return 1 + Math.max(depth(node.left), depth(node.right))
}

复杂度分析:

  • 时间复杂度:O(nlogn),计算 depth 存在大量冗余操作
  • 空间复杂度:O(n)

解答二:自底向上(优化)

解题思路: 利用后续遍历二叉树(左右根),从底至顶返回子树最大高度,判定每个子树是不是平衡树 ,如果平衡,则使用它们的高度判断父节点是否平衡,并计算父节点的高度,如果不平衡,返回 -1

遍历比较二叉树每个节点 的左右子树深度:

  • 比较左右子树的深度,若差值大于 1 则返回一个标记 -1 ,表示当前子树不平衡
  • 左右子树有一个不是平衡的,或左右子树差值大于 1 ,则二叉树不平衡
  • 若左右子树平衡,返回当前树的深度(左右子树的深度最大值 +1

代码实现:

const isBalanced = function (root) {
    return balanced(root) !== -1
};
const balanced = function (node) {
    if (!node) return 0
    const left = balanced(node.left)
    const right = balanced(node.right)
    if (left === -1 || right === -1 || Math.abs(left - right) > 1) {
        return -1
    }
    return Math.max(left, right) + 1
}

复杂度分析:

  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

leetcode

@AnranS
Copy link

AnranS commented Nov 20, 2020

var isBalanced = function(root) {
    function help(root) {
        if(root === null) return 0;
        const left = help(root.left);
        const right = help(root.right);
        if(left === -1 || right === -1 || Math.abs(left - right) > 1) return -1;
        return Math.max(left, right) + 1;
    }
    return help(root) !== -1;
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants