【问题标题】:Java check if binary tree is balancedJava 检查二叉树是否平衡
【发布时间】:2015-01-20 02:22:04
【问题描述】:

这是来自“Cracking the Coding Interview”的一个问题:

实现一个函数来检查一棵树是否平衡。对于这个问题,平衡树被定义为这样一棵树,使得没有两个叶节点与根的距离相差超过一个。

这本书只给出了一个递归的解决方案。我想出了一个使用 BFS 的迭代解决方案,只是想分享它。我做了试运行,但想确保我没有犯错。我也想看看其他人认为他们可以如何改进它。

谢谢!

【问题讨论】:

    标签: java iteration binary-tree binary-search-tree breadth-first-search


    【解决方案1】:
    class Node
    {
    int data;
    LinkedList<Node> children;
    }
    
    public static boolean isBalanced(Node root)
    {
    LinkedList<Node> queue = new LinkedList<Node>();
    queue.offer(root);
    
    int currentLevel = -1, toNextLevel = 0, toNextLevelTemp = 1;
    
    int minLevel = Integer.MAX_VALUE, maxLevel = Integer.MIN_VALUE;
    
    while(!queue.isEmpty())
    {
        if(toNextLevel == 0)
        {
            currentLevel++;
            toNextLevel = toNextLevelTemp;
            toNextLevelTemp = 0;
        }
    
        Node temp = queue.poll();
        toNextLevel--;
    
        //if temp is a leaf, record its depth
        if(temp.children.size() == 0)   
        {
            if(currentLevel < minLevel)
                minLevel = currentLevel;
    
            if(currentLevel > maxLevel)
                maxLevel = currentLevel;
        }
    
        //do whatever with temp
        for(Node child: temp.children)
        {
            queue.add(child);
            toNextLevelTemp++;
        }
    }
    
    //if difference between minLevel and maxLevel is more than 1
    if(maxLevel - minLevel > 1)
        return false;
    
    return true;
    }
    

    【讨论】:

    • 变量“toNextLevel”跟踪到下一级有多少节点。 “toNextLevelTemp”计算在当前关卡中添加到队列中的节点数,并在关卡增加时将其值赋予“toNextLevel”。
    • 我认为这行不通,想想如果你在一侧没有孩子,它会被忽略,这只考虑叶子,如果一个节点的孩子之一为空,那么其他不允许在平衡树中生孩子,把它弄乱,看看我是否能找到一种直观的方法将其整合到这个解决方案中
    【解决方案2】:

    我花了比我预期更长的时间,但是这个解决方案有效,请随意让我的代码更漂亮,在我让它工作后我做了最少的修饰

    /* Returns true if binary tree with root as root is height-balanced */
        boolean isBalanced(Node root) {
            if(root == null) return false;
    
            Deque<Integer> heights = new LinkedList<>();
            Deque<Node> trail = new LinkedList<>();
            trail.push(root);
    
            Node prev = root; //set to root not null to not confuse when root is misisng children
    
            while(!trail.isEmpty()) {
                Node curr = trail.peek(); //get the next node to process, peek because we need to maintain trail until we return
    
                //if we just returned from left child
                if (curr.left == prev) {
                    if(curr.right != null) trail.push(curr.right); //if we can go right go
                    else {
                        heights.push(-1); //otherwise right height is -1 does not exist and combine heights
                        if(!combineHeights(heights)) return false;
                        trail.pop(); //back to parent
                    }
                }
                //if we just returned from right child
                else if (curr.right == prev) {
                    if(!combineHeights(heights)) return false;
                    trail.pop(); //up to parent
                }
                //this came from a parent, first thing is to visit the left child, or right if no left
                else {
                    if(curr.left != null) trail.push(curr.left);
                    else {
                        if (curr.right != null) {
                            heights.push(-1); //no left so when we combine this node left is 0
                            trail.push(curr.right); //since we never go left above logic does not go right, so we must here
                        }
                        else { //no children set height to 1
                            heights.push(0);
                            trail.pop(); //back to parent
                        }
                    }
                }
    
                prev = curr;
            }
    
            return true;
        }
    
        //pop both previous heights and make sure they are balanced, if not return false, if so return true and push the greater plus 1
        private boolean combineHeights(Deque<Integer> heights) {
            int rightHeight = heights.pop();
            int leftHeight = heights.pop();
    
            if(Math.abs(leftHeight - rightHeight) > 1) return false;
            else heights.push(Math.max(leftHeight, rightHeight) + 1);
            return true;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-24
      • 1970-01-01
      • 2015-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多