判断给定的二叉树是否是平衡的
在这个问题中,定义平衡二叉树为每个节点的左右两个子树高度差的绝对值不超过1的二叉树
Given a binary tree, determine if it is height-balanced.
For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.
两种方式,一种是前序遍历,判断是否所有的子树都是平衡二叉树。时间复杂度为O(N^2)。一种是后序遍历,把下面子树的深度传上来,时间复杂度为O(N)。
<?php
class Node{
public $left = null;
public $right = null;
public $val;
public function __construct($val) {
$this->val = $val;
}
}
/*
* 这个其实就是判断所有左右子树是否是平衡二叉树,左右子树的高度是否相差1。
* 下面是根据前序遍历来判断所有点是否是平衡二叉树。这种方式子节点都多计算了深度。
* 求一棵树的高度的时间复杂度为O(N),求所有节点的时间复杂度为O(N^2)
*/
//获取每个节点的深度
function getTreeDepth($root) {
if ($root == null) {
return 0;
}
$leftDepth = getTreeDepth($root->left);
$rightDepth = getTreeDepth($root->right);
return $leftDepth > $rightDepth ? $leftDepth + 1 : $rightDepth + 1;
}
//判断每个节点下的子树是否是平衡二叉树
function isBalanced($root) {
if ($root == null) {
return true;
}
$leftDepth = getTreeDepth($root->left);
$rightDepth = getTreeDepth($root->right);
if (($leftDepth - $rightDepth) > 1 && ($leftDepth - $rightDepth) < -1) {
return false;
}
return isBalanced($root->left) && isBalanced($root->right);
}
/*
* 由于上面的算法有很多重复的计算,时间复杂度很高。
* 采用后序遍历,可以先把底下的左右子树判断,然后判断主树。
* 只求了一遍所有节点的深度O(N)
*/
function isBalanced2($root, &$depth) {
if ($root == null) {
$depth = 0;
return true;
}
$leftIs = isBalanced2($root->left, $leftDepth);
$rightIs = isBalanced2($root->right, $rightDepth);
if (!$leftIs || !$rightIs || ($leftDepth - $rightDepth > 1 && $leftDepth - $rightDepth < -1)) {
return false;
}
$depth = $leftDepth > $rightDepth ? $leftDepth + 1 : $rightDepth + 1;
return true;
}
$node1 = new Node(1);
$node2 = new Node(2);
$node3 = new Node(3);
$node4 = new Node(4);
$node5 = new Node(5);
$node6 = new Node(6);
$node7 = new Node(7);
$node1->left = $node2;
$node1->right = $node3;
$node2->right = $node4;
$node3->left = $node5;
$node3->right = $node6;
$node5->left = $node7;
$depth = 0;
$ret = isBalanced2($node1, $depth);
print_r(intval($ret));