算法随想Day15【二叉树】| LC110-平衡二叉树、LC257-二叉树的所有路径、LC404-左叶子之和
LC110. 平衡二叉树
递归做法一次通过,其实也就是对比:某个节点的左子树和右子树的最大深度的绝对值不大于1,即可认为是平衡二叉树
class Solution {
public:
bool flag;
int checkBalanced(TreeNode* root)
{
if (root == nullptr)
{
return 0;
}
int leftheight = checkBalanced(root->left);
int rightheight = checkBalanced(root->right);
if (abs(leftheight - rightheight) > 1)
{
flag = false;
}
int midheight = max(leftheight, rightheight) + 1;
return midheight;
}
bool isBalanced(TreeNode* root)
{
flag = true;
checkBalanced(root);
return flag;
}
};
LC257. 二叉树的所有路径
递归做法一次通过,递归回溯时,再拼接当前节点在前面
vector<string> binaryTreePaths(TreeNode* root)
{
vector<string> str;
if (root == nullptr)
{
return str;
}
vector<string> str1 = binaryTreePaths(root->left);
vector<string> str2 = binaryTreePaths(root->right);
if (str1.empty() != true)
{
for (auto it : str1)
{
str.push_back(to_string(root->val) + "->" + it);
}
}
if (str2.empty() != true)
{
for (auto it : str2)
{
str.push_back(to_string(root->val) + "->" + it);
}
}
if (str1.empty() == true && str2.empty() == true)
{
str.push_back(to_string(root->val));
}
return str;
}
但内存消耗很大,即使抽离vector
void checkPaths(TreeNode* root, vector<string>& str)
{
if (root == nullptr)
{
return;
}
vector<string> str1 = binaryTreePaths(root->left);
vector<string> str2 = binaryTreePaths(root->right);
if (str1.empty() != true)
{
for (auto it : str1)
{
str.push_back(to_string(root->val) + "->" + it);
}
}
if (str2.empty() != true)
{
for (auto it : str2)
{
str.push_back(to_string(root->val) + "->" + it);
}
}
if (str1.empty() == true && str2.empty() == true)
{
str.push_back(to_string(root->val));
}
}
vector<string> binaryTreePaths(TreeNode* root)
{
vector<string> str;
checkPaths(root, str);
return str;
}

Carl讲解:
版本一,故意这样设计参数(vector
版本二,因为没有使用引用传参,所以每个递归层的string path保持与当前节点进行绑定,不会因为往更深层递归时,发生变化。
////版本一
void traversal(TreeNode* cur, vector<int>& path, vector<string>& result) {
//中,中为什么写在这里,因为最后一个节点也要加入到path中
path.push_back(cur->val);
//这才到了叶子节点
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(); // 回溯
}
}
vector<string> binaryTreePaths(TreeNode* root) {
vector<string> result;
vector<int> path;
if (root == NULL) return result;
traversal(root, path, result);
return result;
}
////版本二
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); // 右
}
vector<string> binaryTreePaths(TreeNode* root)
{
vector<string> result;
string path;
if (root == NULL) return result;
traversal(root, path, result);
return result;
}
LC404. 左叶子之和
第一次的写法,是误解了左叶子的概念a,原来指的是叶子节点,而且是属于左孩子的叶子节点。如[1, 2, 3, 4, 5]的结果是4,而不是2 + 4 = 6
int sumOfLeftLeaves(TreeNode* root)
{
int sum = 0;
int leftsum = 0, rightsum = 0;
if (root == nullptr)
{
return sum;
}
if (root->left != nullptr)
{
leftsum += sumOfLeftLeaves(root->left);
}
if (root->right != nullptr)
{
rightsum += sumOfLeftLeaves(root->right);
}
sum = leftsum + rightsum + (root->left == nullptr ? 0 : root->left->val);
return sum;
}
修改下,标记为is_left,且为叶子节点(root->left == nullptr && root->right == nullptr)才计数
int checkLeftLeaves(TreeNode* root, int is_left)
{
int sum = 0;
int leftsum = 0, rightsum = 0;
if (root == nullptr)
{
return sum;
}
if (root->left != nullptr)
{
leftsum += checkLeftLeaves(root->left, 1);
}
if (root->right != nullptr)
{
rightsum += checkLeftLeaves(root->right, 0);
}
sum = leftsum + rightsum + (root->left == nullptr && root->right == nullptr && is_left == 1 ? root->val : 0);
return sum;
}
int sumOfLeftLeaves(TreeNode* root)
{
int sum = 0;
sum = checkLeftLeaves(root, 0);
return sum;
}

浙公网安备 33010602011771号