代码随想Day17 | 110.平衡二叉树 、257. 二叉树的所有路径 、404.左叶子之和

110.平衡二叉树 

这道题用到了求高度的思路,同时可以用一个标志来表示高度差超过1,用后序遍历来完成这道题,递归三步走:

1. 参数: 返回的是树的高度,传入的参数就是节点;

2. 结束条件: 如果节点等于空,则其高度为0;

3. 单层处理逻辑:首先是左右节点,然后再处理中间节点,这里有个设计巧妙的地方,当两个节点的高度已经超过1时候,就没有必要再向上判断了,直接传一个标志,一直传到根节点即可,否则的话计算返回当前节点的高度。

详细代码如下:

class Solution {
public:
    int dfs(TreeNode* root)
    {
        if(root==nullptr) return 0;
        int left = dfs(root->left);    //左
        int right = dfs(root->right);  //右
        //中
        if(left==-1||right==-1) return -1;
        if(abs(left-right)>1) return -1;
        return 1+max(left,right);
    }
    bool isBalanced(TreeNode* root) {
        //运用后序遍历
        if(dfs(root)==-1) return false;
        else return true;
    }
};

 257. 二叉树的所有路径 

这道题目中涉及到回溯,因为需要记录所有路径,所以有一个添加元素然后去掉元素的过程,在我的写法中,我把这个回溯的过程隐藏在了递归到下一层时tmp变量的变化中,详细代码如下:

此外在写这道题时我还遇到了语法不熟的问题:

1. 在函数参数中想要改变vector里面的元素时,要使用引用传递,这样函数内部就使用vector的引用,任何修改都会导致vector的变化,然而使用值传递,函数会复制一份副本,在函数内部使用该副本,不会影响原始的vector;

2. 数字转换成字符的库函数是 to_stirng(val)或者itoa(val);

详细代码如下:

class Solution {
public:
    void dfs(TreeNode* root, string tmp, vector<string>& res)
    {
        if(root==nullptr)return;
        if(root->left==nullptr&&root->right==nullptr)
        {
            res.push_back(tmp+to_string(root->val));
            return;
        }
        dfs(root->left,tmp+to_string(root->val)+"->",res);
        dfs(root->right,tmp+to_string(root->val)+"->",res);
    }
    vector<string> binaryTreePaths(TreeNode* root) {
        vector<string> res;
        if(root==nullptr) return {};
        string tmp;
        dfs(root,tmp,res);
        return res;
    }
};

404.左叶子之和

这道题目我自己写出来了,我的思路是要到左叶子的上一层就要进行加操作,否则很难判断,按照我的思路写了代码,但是我在写的时候结束条件没有弄清楚,我用到的是先序遍历,到最后是调试出来的正确结果,没有return值的时候可ac,思路没有完全清晰,我自己写的代码如下:

class Solution {
public:
    void dfs(TreeNode* root, int& res)
    {
        //if(root->left==nullptr) return;
        if(root->left!=nullptr&&root->left->left==nullptr&&root->left->right==nullptr)
        {
            res+=root->left->val;
            //return;
        }
        if(root->left) dfs(root->left,res);
        if(root->right) dfs(root->right,res);
    }
    int sumOfLeftLeaves(TreeNode* root) {
        int res=0;
        dfs(root,res);
        return res;
    }
};

学习代码随想录的思想:

递归三部曲:

1. 确定递归函数的参数和返回值

判断一个树的左叶子节点之和,那么一定要传入树的根节点,递归函数的返回值为数值之和,所以为int,使用题目中给出的函数就可以了。

2. 确定终止条件

如果遍历到空节点,那么左叶子值一定是0

if (root == NULL) return 0;

注意,只有当前遍历的节点是父节点,才能判断其子节点是不是左叶子。 所以如果当前遍历的节点是叶子节点,那其左叶子也必定是0,那么终止条件为:

if (root == NULL) return 0;
if (root->left == NULL && root->right== NULL) return 0; //其实这个也可以不写,如果不写不影响结果,但就会让递归多进行了一层。

3. 确定单层递归的逻辑

当遇到左叶子节点的时候,记录数值,然后通过递归求取左子树左叶子之和,和 右子树左叶子之和,相加便是整个树的左叶子之和。

详细代码如下:

class Solution {
public:
    int sumOfLeftLeaves(TreeNode* root) {
        if(root==nullptr) return 0;
        if(root->left==nullptr&&root->right==nullptr) return 0;
        int left = sumOfLeftLeaves(root->left);//左
        if(root->left&&root->left->left==nullptr&&root->left->right==nullptr) left=root->left->val;
        int right = sumOfLeftLeaves(root->right);//右
        return left+right; //中
    }
};

通过学习代码随想录的思想,理清了自己的思路,我自己的思路是前序遍历,结束条件是root==nullprt,单层的处理逻辑里,添加元素的部分为中,依次是左右,清晰思路后的代码如下:

class Solution {
public:
    void dfs(TreeNode* root, int &res)
    {
        if(root==nullptr) return;
        if(root->left!=nullptr&&root->left->left==nullptr&&root->left->right==nullptr)  
        //中
        {
            res+=root->left->val;
        }
        dfs(root->left, res); //左
        dfs(root->right, res); //右
    }
    int sumOfLeftLeaves(TreeNode* root) {
        int res = 0;
        dfs(root, res);
        return res;

    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值