平衡二叉树
题目描述
力扣链接🔗

题目分析
高度和深度的概念在二叉树概述中。此题注意:而根节点的高度就是这棵树的最大深度。
代码
递归法
- 明确递归函数的参数和返回值
参数:当前传入节点。
返回值:以当前传入节点为根节点的树的高度。
那么如何标记左右子树是否差值大于1呢?如果当前传入节点为根节点的二叉树已经不是二叉平衡树了,还返回高度的话就没有意义了。所以如果已经不是二叉平衡树了,可以返回-1 来标记已经不符合平衡树的规则了。 - 明确终止条件
递归的过程中依然是遇到空节点了为终止,返回0,表示当前节点为根节点的树高度为0。 - 单层循环
求当前左子树和右子树的高度差,如果相差大于一,那么就已经不是平衡二叉树了,此时需要将结果返回-1,标志此时已经不是平衡二叉树。如果上一次递归返回的结果为-1,那么直接返回-1,表示不是平衡二叉树。 
/*** 后序递归法* @param root* @return*/public boolean isBalanced(TreeNode root) {return getHeight(root) == -1 ? false : true;}// -1表示此时高度差已经大于1public int getHeight(TreeNode root) {if (root == null) {return 0;}int leftHeight = getHeight(root.left); // 左if (leftHeight == -1) return -1;int rightHeight = getHeight(root.right);// 右if (rightHeight == -1) return -1;if (Math.abs(leftHeight - rightHeight) > 1) { // 中return -1; // 左右子树高度相差大于1,返回-1} else {return 1 + Math.max(leftHeight, rightHeight); // 左右子树高度相差小于1,此节点作为根节点的高度就为最大深度}}
先序也可以
public boolean isBalanced(TreeNode root) {if (root == null) {return true;}if (isBalanced(root.left) == false) return false;if (isBalanced(root.right) == false) return false;int left = traversal(root.left);int right = traversal(root.right);return Math.abs(left - right) <= 1;}public int traversal(TreeNode root) {if (root == null) {return 0;}int left = traversal(root.left);int right = traversal(root.right);return 1 + Math.max(left, right);}
迭代法
定义一个求深度的方法,每次遍历一个节点就求其深度,然后再按照上述递归法思路判断左右孩子是否相差1。
/*** 迭代法(时间复杂度O(n ^ n))** @param root* @return*/public boolean isBalanced(TreeNode root) {if (root == null) return true;// 然后再用栈来模拟前序遍历,遍历每一个节点的时候,再去判断左右孩子的高度是否符合Stack<TreeNode> stack = new Stack<>();stack.push(root);int leftHeight = 0, rightHeight = 0;while (!stack.isEmpty()) {TreeNode node = stack.pop();leftHeight = getHeight(node.left);rightHeight = getHeight(node.right);if (Math.abs(leftHeight - rightHeight) > 1) { // 中return false;} else {if (node.right != null) isBalanced(node.right); // 右(空节点不入栈)if (node.left != null) isBalanced(node.left); // 左(空节点不入栈)}}return true;}/*** 层序求深度** @param root* @return*/public int getHeight(TreeNode root) {if (root == null) {return 0;}Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);int height = 0;while (!queue.isEmpty()) {int len = queue.size();height++;while (len > 0) {TreeNode node = queue.poll();if (node.left != null) queue.offer(node.left);if (node.right != null) queue.offer(node.right);len--;}}return height;}
求深度适合用前序遍历,而求高度适合用后序遍历。
