目录:
解题及思路学习
110.平衡二叉树
https://leetcode.cn/problems/balanced-binary-tree/
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。
示例 1:
!https://assets.leetcode.com/uploads/2020/10/06/balance_1.jpg
输入:root = [3,9,20,null,null,15,7]
输出:true
思考:这题用迭代法好像不是特别好求。用递归试试。递归中用一个数,例如 - 1 来表示不满足,这样就可以简化参数。
cpp
class Solution {
public:
int getHeight(TreeNode* root) {
if (root == NULL) return 0;
int left = getHeight(root->left);
if (left == -1) return -1;
int right = getHeight(root->right);
if (right == -1) return -1;
return abs(left - right) > 1 ? -1 : max(left, right) + 1;
}
bool isBalanced(TreeNode* root) {
return getHeight(root) == -1 ? false : true;
}
};
257. 二叉树的所有路径
https://leetcode.cn/problems/binary-tree-paths/
给你一个二叉树的根节点 root
,按 任意顺序 ,返回所有从根节点到叶子节点的路径。
叶子节点 是指没有子节点的节点。
示例 1:
!https://assets.leetcode.com/uploads/2021/03/12/paths-tree.jpg
输入:root = [1,2,3,null,5]
输出:["1->2->5","1->3"]
思考:主要是模拟最后保存结果的过程。
cpp
// 版本一
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;
}
};
c++写代码中,如果最后的处理节点在空节点处,则遍历的时候不用加 if(cur→left) 这样的判断条件。如果处理的节点是在叶子节点,则空节点不进入处理的逻辑,需要加判断条件。
404.左叶子之和
https://leetcode.cn/problems/sum-of-left-leaves/
给定二叉树的根节点 root
,返回所有左叶子之和。
示例 1:
!https://assets.leetcode.com/uploads/2021/04/08/leftsum-tree.jpg
输入: root = [3,9,20,null,null,15,7]
输出: 24
解释: 在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24
思考:处理逻辑是当遇到左叶子节点的时候,返回左叶子节点的值。但是判断左叶子节点还需要父节点。
cpp
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
if (root == NULL) return 0;
if (root->left == NULL && root->right == NULL) return 0;
int left = sumOfLeftLeaves(root->left);
if (root->left && root->left->left == NULL && root->left->right == NULL) {
left = root->left->val;
}
int right = sumOfLeftLeaves(root->right);
return left + right;
}
};
迭代法:
这里用了栈作为容器。使用前序遍历。
cpp
class Solution {
public:
int sumOfLeftLeaves(TreeNode* root) {
stack<TreeNode*> st;
if (root == NULL) return 0;
st.push(root);
int result = 0;
while(!st.empty()) {
TreeNode* node = st.top();
st.pop();
if (node->left && !node->left->left && !node->left->right) {
result += node->left->val;
}
if (node->right) st.push(node->right);
if (node->left) st.push(node->left);
}
return result;
}
};
复盘总结
个人反思
1、c++写代码中,如果最后的处理节点在空节点处,则遍历的时候不用加 if(cur→left) 这样的判断条件。如果处理的节点是在叶子节点,则空节点不进入处理的逻辑,需要加判断条件。
2、使用to_string函数可以将数字转换为字符串, 返回值为转换完的字符串。默认情况下,to_string默认输出6位小数,但这不一定是您想要的。C ++ 11引入了std :: to_string的另一个重载版本,该版本接受一个小数位数参数。
头文件:include<cstring>
cpp
std::to_string
string to_string (int val);
string to_string (long val);
string to_string (long long val);
string to_string (unsigned val);
string to_string (unsigned long val);
string to_string (unsigned long long val);
string to_string (float val);
string to_string (double val);
string to_string (long double val);