力扣 - 剑指 Offer 55 - II. 平衡二叉树
2021-11-24 22:51
197 查看
题目
思路1(后序遍历+剪枝)
- 这题是上一题剑指 Offer 55 - I. 二叉树的深度的进阶,逻辑代码和那个一样,也是后续遍历,获取两个子节点较大的那个深度再加上当前一层返回给父节点,是自底向上的
- 也为要求是否为平很二叉树,要保证他的左子树和右子树差值不大于1,那么我们就在每次获取左右子树的深度的时候再加一个判断就好啦~
- 但是我们可以进行剪枝优化,如果不剪枝,就算判定为不是平衡二叉树,那么它还是会递归遍历完。当发现不是平衡二叉树的时候,我们返回 -1 ,然后在每次获取完左右子树节点的深度时候,判断是否等于 -1,这样就可以减少不必要的递归了!
代码
class Solution { public boolean isBalanced(TreeNode root) { // 只要返回值不是-1,说明就是平衡二叉树 return dfs(root) != -1; } public int dfs(TreeNode root) { if (root == null) { return 0; } int l = dfs(root.left); // 剪枝,返回 -1 说明不是平衡二叉树了 if (l == -1) { return -1; } int r = dfs(root.right); // 同上 if (r == -1) { return -1; } // 判断左右子树的深度吃的差值是否大于1 if (Math.abs(l - r) > 1) { return -1; } return 1 + Math.max(l, r); } }
复杂度分析
- 时间复杂度:O(N)
- 空间复杂度:O(N)
思路2(前序遍历)
- 后序遍历是一种自底向上的方法,只需要遍历一遍链表即可。不过我们也可以使用自顶向下方法,从根节点向下,先判断左右两个子树是否平衡,然后再递归判断子树,不过这样会导致很多节点被重复遍历了,时间复杂度比较高。。
代码
class Solution { public boolean isBalanced(TreeNode root) { if (root == null) { return true; } // 先判断左右两个子树是否平衡,不平衡的话返回false int l = treeDeepth(root.left); int r = treeDeepth(root.right); if (Math.abs(l - r) > 1) { return false; } // 然后在继续判断他的左右子树是否平衡(前序遍历) return isBalanced(root.left) && isBalanced(root.right); } public int treeDeepth(TreeNode root) { if (root == null) { return 0; } int l = treeDeepth(root.left); int r = treeDeepth(root.right); return 1 + Math.max(l, r); } }
复杂度分析
- 时间复杂度:O(N^2)
- 空间复杂度:O(N)
相关文章推荐
- 【Golang】LeetCode-剑指Offer-面试题55 - II -平衡二叉树
- 力扣 - 剑指 Offer 57 - II. 和为s的连续正数序列
- 【剑指Offer】II. 平衡二叉树
- 力扣 - 剑指 Offer 58 - II. 左旋转字符串
- 力扣 - 剑指 Offer 32 - II. 从上到下打印二叉树 II
- 【剑指offer】面试题55(2):平衡二叉树
- 剑指offer之面试题55(2):平衡二叉树
- 力扣 - 剑指 Offer 10- II. 青蛙跳台阶问题
- 剑指Offer面试题55-2:平衡二叉树
- 力扣 - 剑指 Offer 59 - II. 队列的最大值
- 力扣 - 剑指 Offer 53 - II. 0~n-1中缺失的数字
- 【剑指Offer】II. 数组中数字出现的次数 II
- 剑指offer 面试题39 求二叉树深度|判断是否为平衡二叉树
- 剑指offer——面试题39-2:平衡二叉树
- 剑指 Offer 14- II. 剪绳子 II
- 力扣 - 剑指 Offer 57. 和为s的两个数字
- 力扣 - 剑指 Offer 22. 链表中倒数第k个节点
- 剑指offer——平衡二叉树
- 剑指offer 平衡二叉树
- 剑指offer55