java—寻找树是否平衡的迭代解决方案

gdx19jrr  于 2021-07-13  发布在  Java
关注(0)|答案(3)|浏览(323)

所以有人发布了他们的解决方案,但我发现它似乎不起作用,我发布了这个,但我想让其他人更容易访问它。
问题在“破解代码面试”中,这是第一个树形问题,请随意提出其他建议(或证明我错了!)

hwazgwia

hwazgwia1#

这里的关键是很难用一个堆栈跟踪最终路径及其高度。
我最后做的是把左右两个孩子的身高都推到一个堆栈上,检查他们是否在一个里面,把一个加到最大值上,然后在弹出左右两个之后把这个推到堆栈上。
我已经评论过了,所以我希望它足够清晰

/* 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;
        }
m4pnthwp

m4pnthwp2#

书中最初的问题没有提到树是二进制的。我碰巧解决了同样的问题,但用python编写。所以,这里是我用python迭代解决这个问题的方法,对于一般树(节点的子节点存储在一个列表中)。

def is_balanced_nonrecursive(self):
    stack = [self.root]
    levels = [0]
    current_min = sys.maxint
    current_max = 0
    current_level = 0
    while len(stack) > 0:
        n = stack.pop()
        current_level = levels.pop()
        for c in n.children:
            stack.append(c)
            levels.append(current_level + 1)
        if len(n.children) == 0:
            if current_level < current_min:
                current_min = current_level
            if current_level > current_max:
                current_max = current_level
    return current_max - current_min < 2

这基本上是树的深度优先遍历。我们为级别(列表)保留一个单独的堆栈 levels ). 如果我们看到任何叶节点,我们会相应地更新当前最小值和当前最大值。该算法遍历整棵树,最后如果最大和最小级别相差一个以上,则树是不平衡的。
有许多优化是可能的,比如检查min和max的差在循环中是否不止一个,如果是这样的话返回 False 马上。

fumotvh3

fumotvh33#

这段代码有一些重复,但至少不像递归代码那样让我头疼:

public boolean isBalanced() {
    Queue<TreeNode> queue = new LinkedList<TreeNode>();
    int leftLevel = 0;
    int rightLevel = 0;
    if(this == null) return false;
    if(this.left != null)queue.offer(this.left);

    while(!queue.isEmpty()) {
        int size = queue.size();
        for(int i=0; i < size; i++) {
            if(queue.peek().left != null) queue.offer(queue.peek().left);
            if(queue.peek().right != null) queue.offer(queue.peek().right);
            queue.poll();
        }
        leftLevel++;
    }

    if(this.right != null) queue.offer(this.right);

    while(!queue.isEmpty()) {
        int size = queue.size();
        for(int i=0; i < size; i++) {
            if(queue.peek().left != null) queue.offer(queue.peek().left);
            if(queue.peek().right != null) queue.offer(queue.peek().right);
            queue.poll();
        }
        rightLevel++;
    }
    return Math.abs(leftLevel - rightLevel) < 2;
}

相关问题