/* 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;
}
3条答案
按热度按时间hwazgwia1#
这里的关键是很难用一个堆栈跟踪最终路径及其高度。
我最后做的是把左右两个孩子的身高都推到一个堆栈上,检查他们是否在一个里面,把一个加到最大值上,然后在弹出左右两个之后把这个推到堆栈上。
我已经评论过了,所以我希望它足够清晰
m4pnthwp2#
书中最初的问题没有提到树是二进制的。我碰巧解决了同样的问题,但用python编写。所以,这里是我用python迭代解决这个问题的方法,对于一般树(节点的子节点存储在一个列表中)。
这基本上是树的深度优先遍历。我们为级别(列表)保留一个单独的堆栈
levels
). 如果我们看到任何叶节点,我们会相应地更新当前最小值和当前最大值。该算法遍历整棵树,最后如果最大和最小级别相差一个以上,则树是不平衡的。有许多优化是可能的,比如检查min和max的差在循环中是否不止一个,如果是这样的话返回
False
马上。fumotvh33#
这段代码有一些重复,但至少不像递归代码那样让我头疼: