算法随想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 str为引用也是如此

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& path),是想体现出回溯的这个过程,因为path是传引用,所以多次递归对该数组都是公用一块内存区域的。所以当回溯到某个节点时,此时的path数组却还保留着其深层的模样,因此若想还原到当前节点在递归更深层前的path数组模样的话,就要显性的对path进行回溯操作(path.pop_back();)。

版本二,因为没有使用引用传参,所以每个递归层的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;
}
posted @ 2023-02-17 23:39  冥紫将  阅读(12)  评论(0)    收藏  举报