平衡二叉树
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。
示例 1:
给定二叉树 [3,9,20,null,null,15,7]
返回 true 。
示例 2:
给定二叉树 [1,2,2,3,3,null,null,4,4]
返回 false
根节点的深度究竟是1 还是 0,不同的地方有不一样的标准,leetcode的题目中都是以节点为一度,即根节点深度是1;
维基百科上定义用边为一度,即根节点的深度是0,此处暂时以leetcode为准;
【补充】:若想实现真正的深度遍历,应该使用前序遍历(中左右):
class Solution {
public:
int result;
void getDepth(TreeNode* node, int depth) {
result = depth > result ? depth : result; // 中
if (node->left == NULL && node->right == NULL) return ;
if (node->left) { // 左
depth++; // 深度+1
getDepth(node->left, depth);
depth--; // 回溯,深度-1
}
if (node->right) { // 右
depth++; // 深度+1
getDepth(node->right, depth);
depth--; // 回溯,深度-1
}
return ;
}
int maxDepth(TreeNode* root) {
result = 0;
if (root == NULL) return result;
getDepth(root, 1);
return result;
}
};
回归到这道题,解决的思路还是求最大高度,那自然还是后序遍历(左右中),判断最大高度差是否小于等于一;
//递归第一步:确定递归函数的参数类型和返回值
//当子树已经不是平衡二叉树的时候,直接返回-1,否则返回
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(abs(leftHeight - rightHeight) > 1) return -1;
else return 1 + max(leftHeight,rightHeight);
}
具体代码如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
//递归第一步:确定递归函数的参数类型和返回值
//当子树已经不是平衡二叉树的时候,直接返回-1,否则返回
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;
return abs(leftHeight - rightHeight) > 1? -1 :1 + max(leftHeight,rightHeight);
}
bool isBalanced(TreeNode* root) {
return GetHeight(root) == -1 ? false :true;
}
};
二叉树的所有路径
给定一个二叉树,返回所有从根节点到叶子节点的路径。
说明: 叶子节点是指没有子节点的节点。
示例:
输出格式先不考虑其中的->,那就是先输出父节点再输出子节点,则使用前序遍历(中左右);
这里引入回溯的概念:
递归函数代码实现如下:
void traversal(TreeNode* cur, vector<int>& path, vector<string>& result) {
path.push_back(cur->val); // 中,中为什么写在这里,因为最后一个节点也要加入到path中
// 这才到了叶子节点
if (cur->left == NULL && cur->right == NULL) {
string sPath;
for (int i = 0; i < path.size() - 1; i++) {
sPath += to_string(path[i]);//to_string将值转化为string类型
sPath += "->";
}
sPath += to_string(path[path.size() - 1]);
result.push_back(sPath);
return;
}
if (cur->left) { // 左
traversal(cur->left, path, result);
path.pop_back(); // 回溯
}
if (cur->right) { // 右
traversal(cur->right, path, result);
path.pop_back(); // 回溯
}
}
具体代码实现如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
private:
void traversal(TreeNode* cur, vector<int>& path, vector<string>& result) {
path.push_back(cur->val); // 中,中为什么写在这里,因为最后一个节点也要加入到path中
// 这才到了叶子节点
if (cur->left == NULL && cur->right == NULL) {
string sPath;
for (int i = 0; i < path.size() - 1; i++) {
sPath += to_string(path[i]);
sPath += "->";
}
sPath += to_string(path[path.size() - 1]);
result.push_back(sPath);
return;
}
if (cur->left) { // 左
traversal(cur->left, path, result);
path.pop_back(); // 回溯
}
if (cur->right) { // 右
traversal(cur->right, path, result);
path.pop_back(); // 回溯
}
}
public:
vector<string> binaryTreePaths(TreeNode* root) {
vector<string> result;
vector<int> path;
if (root == NULL) return result;
traversal(root, path, result);
return result;
}
};
左叶子之和
计算给定二叉树的所有左叶子之和。
示例:
判断当前节点是不是左叶子是无法判断的,必须要通过节点的父节点来判断其左孩子是不是左叶子;
//参数和返回值
int traversal(TreeNode* node){
//终止条件
if(node == NULL) return 0;
if(node->left == NULL && node->right == NULL) return 0;
//单层遍历逻辑
int leftNum = traversal(node->left);//左
if(root->left != NULL && root->left->left == NULL && root->left->right == NULL){
leftNum = root->left->val;
}
int rightNum = traversal(node->right);//右
return leftNum + rightNum;//中
}
题目所需代码可以直接使用这个递归函数得到要求结果,不再赘述。