目录
题目链接:https://leetcode.cn/problems/balanced-binary-tree/
题目链接:https://leetcode.cn/problems/binary-tree-paths/
题目链接:https://leetcode.cn/problems/sum-of-left-leaves/
题目:110. 平衡二叉树
题目链接:https://leetcode.cn/problems/balanced-binary-tree/
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。
示例 1:
给定二叉树 [3,9,20,null,null,15,7]
返回 true 。
示例 2:
给定二叉树 [1,2,2,3,3,null,null,4,4]
返回 false 。
思路: 求出每个节点的左右子树的高度,左右子树的高度相差>1则说明不是平衡二叉树,返回-1,否则返回整棵树的最大高度。最后主函数调用递归函数,判断是否返回的值是否是-1,如果是则返回false,反之,则返回true
递归:
class Solution {
public:
// 返回以该节点为根节点的二叉树的高度,如果不是平衡二叉树了则返回-1
int getHeight(TreeNode* node) {
if (node == NULL) {
return 0;
}
int leftHeight = getHeight(node->left);
if (leftHeight == -1) return -1;
int rightHeight = getHeight(node->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;
}
};
题目:257.二叉树的所有路径
题目链接:https://leetcode.cn/problems/binary-tree-paths/
给定一个二叉树,返回所有从根节点到叶子节点的路径。
说明: 叶子节点是指没有子节点的节点。
示例:
思路:
确定递归函数的参数和返回值:
- 不需要对返回值进行处理,返回值类型为void,传入参数为根节点,记录一条路径的path,结果集result
确定终止条件:
- 遍历到叶子节点就不走了,把路径加入到结果集中
确定单层逻辑:
- 使用前序遍历,注意这里要使用回溯。
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;
}
};
精简版本:
class Solution {
private:
void traversal(TreeNode* cur, string path, vector<string>& result) {
path += to_string(cur->val); // 中
if (cur->left == NULL && cur->right == NULL) {
result.push_back(path);
return;
}
if (cur->left) traversal(cur->left, path + "->", result); // 左
if (cur->right) traversal(cur->right, path + "->", result); // 右
}
public:
vector<string> binaryTreePaths(TreeNode* root) {
vector<string> result;
string path;
if (root == NULL) return result;
traversal(root, path, result);
return result;
}
};
题目:404.左叶子之和
题目链接:https://leetcode.cn/problems/sum-of-left-leaves/
计算给定二叉树的所有左叶子之和。
示例:
思路:先找到所有左叶子,返回所有左叶子之和。
怎么判断当前遍历的节点是左叶子?
判断该节点是否是左叶子必须通过其父节点,如果父节点的左孩子不为空,而且父节点的左孩子的左右孩子为空,则说明该节点为左叶子节点。
递归:
确定递归函数的参数和返回值:
- 因为要返回左叶子之和,因此返回值为int,传入的参数为根节点。
确定终止条件:
- 如果遍历到了空节点,则返回0,这里还可以加一句如果遍历到了叶子节点,也返回0,(这样做可以让递归少进行一层)。
确定单层逻辑:
- 求根节点左子树的所有左叶子的和,和根节点右子树的所有左叶子之和,然后相加就是整棵树的左叶子之和。
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
if (root == NULL) return 0;
if (root->left == NULL && root->right== NULL) return 0;
int leftValue = sumOfLeftLeaves(root->left); // 左
if (root->left && !root->left->left && !root->left->right) { // 左子树就是一个左叶子的情况
leftValue = root->left->val;
}
int rightValue = sumOfLeftLeaves(root->right); // 右
int sum = leftValue + rightValue; // 中
return sum;
}
};
精简版本:
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
if (root == NULL) return 0;
int leftValue = 0;
if (root->left != NULL && root->left->left == NULL && root->left->right == NULL) {
leftValue = root->left->val;
}
return leftValue + sumOfLeftLeaves(root->left) + sumOfLeftLeaves(root->right);
}
};