剑指 Offer 55

思路

方法一:暴力递归法 (自顶向下的递归)

使用递归编写一个求高度的函数,之后使用先序遍历每个结点,判断左右子树的高度差是否满足要求。

这种方法每次判断一个结点都需要使用递归先求出其左右子树的高度,比如下面这棵树,判断1的时候,使用递归求了2,3, 4的高度,判断2的时候,又递归求了3,4,的高度,这样就重复求了很多次,产生了很多重叠子问题。

所以我们需要改进此算法,可以从底部往上边求高度边判断是否平衡,同时进行剪枝。(改进的算法见下文方法二)

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 8  *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 9  *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
10  * };
11  */
12 class Solution {
13 public:
14     bool isBalanced(TreeNode* root) {
15         if (root == NULL) 
16             return true;
17         return check(root);
18     }
19 
20     int depth(TreeNode* root) {
21         if (root == NULL) 
22             return 0;
23         return 1 + max(depth(root->left), depth(root->right));
24     }
25 
26     //先序遍历检验每个节点
27     bool check(TreeNode* root) {
28         if (root == NULL) 
29             return true;
30         if(depth(root->left) - depth(root->right) >= 2 || depth(root->right) - depth(root->left) >= 2) 
31             return false;
32         
33         return check(root->left) && check(root->right);
34     }
35 };

方法二:后序遍历 + 剪枝 (自底向上的递归)

方法一是遍历所有结点,对每个结点都进行求高度判断。

这里改进之后是:边求高度边判断。

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     bool isBalanced(TreeNode* root) {
13         bool flag = true;
14         postOrderTraerse(root, flag);
15         return flag;
16     }
17 
18     int postOrderTraerse(TreeNode* root, bool &flag) {
19         if(root == NULL || !flag)   //使用flag剪枝
20             return 0;
21         
22         int ldepth = postOrderTraerse(root->left, flag);
23         int rdepth = postOrderTraerse(root->right, flag);
24 
25         if(ldepth - rdepth >= 2 || rdepth - ldepth >= 2) {
26             flag = false;   //不是平衡树,将flag置为false,后续直接返回
27             return 0;
28         }
29 
30         return 1 + max(ldepth, rdepth);
31     }
32 };

参考

力扣官方题解 - 平衡二叉树

原文地址:https://www.cnblogs.com/FengZeng666/p/13953987.html