这个代码应该改变啥才能正确识别平衡树?

Posted

技术标签:

【中文标题】这个代码应该改变啥才能正确识别平衡树?【英文标题】:What should change for the this code to correctly identify balanced Trees?这个代码应该改变什么才能正确识别平衡树? 【发布时间】:2022-01-01 05:52:13 【问题描述】:

我正在做this leetcode problem。 我已经完成了另一个使用高度函数的实现。这行得通。

我有这个其他的实现。从视觉上看,当我查看问题时,我会明白为什么它不起作用。但我找不到文字来为自己写下它为什么不起作用。 它在 [1, 2, 2, 3, 3, null, null, 4, 4] 的第 214 次测试中失败了

class Solution 
    // for every node I have to go 2 levels down. 
    // if left existed, then see if right exists, and traverse down 
    // if left existed and had children but right didn't exist then return `false`
    // or if right existed and had children but left didn't exist then return `false`
    func isBalanced(_ root: TreeNode?) -> Bool 
        if let left = root?.left 
            if let right = root?.right 
                return isBalanced(left) && isBalanced(right)
             else if left.left != nil || left.right != nil 
                    return false
                
         else if let right = root?.right 
            if root?.left == nil 
                if right.left != nil || right.right != nil 
                    return false
                
            
        
        return true
    

需要明确的是,我不是在寻找替代解决方案。我只是想了解为什么当前的实现不起作用。

【问题讨论】:

在“第 2 级”上,您会发现 left 和 right 都返回 isBalanced(left) && isBalanced(right) - 这两者都是必要条件(every 节点的子树高度不同不超过 1)。但这还不够,因为它们的高度可能 - 你猜对了 - 相差两个(如这里)或更多。只需返回每个子树的高度,找出它们的最小值、最大值和差值。 【参考方案1】:

这不是替代解决方案,我只是删除了不必要的检查...

class TreeNode 
    constructor(left, right) 
        this.left = left
        this.right = right
    
    isEndNode()  return this.left == null && this.right == null; 
    isBalanced() 
        if (this.isEndNode()) return true;

        if (this.left && this.right)
            return this.left.isBalanced() && this.right.isBalanced();

        return false
    

let node = (left, right) => new TreeNode(left, right);

let root1 = node(node(node(), node()), node(node(), node()))
let root2 = node(node(node(), node()), node(node(), null))
let root3 = node(node(null, node()), node(node(), node()))

console.log(root1.isBalanced()) // true
console.log(root2.isBalanced()) // false
console.log(root3.isBalanced()) // false

【讨论】:

三个中有两个不需要的结果。添加let root4 = node(null, node(node(node(), node()), node(node(), node())) 两个不需要的结果??? For this problem, a height-balanced binary tree is defined as[a]tree in which the left and right subtrees of every node differ in height by no more than 1.【参考方案2】:

以这棵树为例:

                  8
                /   \
               4     9
             /   \
            2     6
           / \   / \
          1   3 5   7

从根开始,这段代码的执行将进入内部if块:

    if let left = root?.left 
        if let right = root?.right 
            return isBalanced(left) && isBalanced(right)

...两个递归调用将返回 true,因为确实这些子树本身是平衡的,因此这棵树将被识别为平衡的。但很明显情况并非如此。

您确实需要检索子树的高度并进行比较。

【讨论】:

以上是关于这个代码应该改变啥才能正确识别平衡树?的主要内容,如果未能解决你的问题,请参考以下文章

可持久化平衡树详解及实现方法分析

二叉平衡树的实现(c语言编程)

二叉树的深度平衡是啥意思?

洛谷 P3835 模板可持久化平衡树

数据结构:查找|| 平衡二叉树

BZOJ2329 HNOI2011 括号修复 平衡树