代码随想录算法训练营第十八 |513.找树左下角的值、112. 路径总和、113.路径总和ii 、106.从中序与后序遍历序列构造二叉树

513.找树左下角的值

题目链接/文章讲解/视频讲解:https://programmercarl.com/0513.%E6%89%BE%E6%A0%91%E5%B7%A6%E4%B8%8B%E8%A7%92%E7%9A%84%E5%80%BC.html

 //我的思路:层序遍历,输出最后一层的第一个元素
 //实际上,使用result保存每一层的第一个元素,最后存的是最后一层的最左侧元素
class Solution {
public:
    // int maxDepth(TreeNode* root)
    // {
    //     if(root==NULL) return 0;
    //     int left = maxDepth(root->left);
    //     int right = maxDepth(root->right);
    //     return 1+max(left,right);
    // }
    int findBottomLeftValue(TreeNode* root) {
        queue<TreeNode*> que;
        // vector<int> result;
        if(root != NULL) que.push(root);
        // int depth = maxDepth(root);
        int result = 0;
        while(!que.empty()){
            int size = que.size();
            
            for(int i=0;i<size;i++)
            {
                TreeNode* node = que.front();
                que.pop();
                //这一行很关键
                if(i==0) result = node->val;
                if(node->left) que.push(node->left);
                if(node->right) que.push(node->right);
            }
        }
        return result;
    }
};

112. 路径总和

题目链接/文章讲解/视频讲解:https://programmercarl.com/0112.%E8%B7%AF%E5%BE%84%E6%80%BB%E5%92%8C.html

 //递归思想,终止条件、回溯条件:子节点+最后的值为0(true)不为0(false)
            //递归条件,有左孩 / 右孩,传入左/右孩和减去左/右孩后的值,
            //注意一条路径走到头false了 要进行回溯
class Solution {
private:
    bool traversal(TreeNode* root, int temp_sum){
        if(!root->left && !root->right && temp_sum==0)
            return true;
        else if(!root->left && !root->right)
            return false;
        if(root->left)
        {
            temp_sum -= root->left->val;
            if(traversal(root->left, temp_sum)) return true;
             //否则,回溯
            temp_sum += root->left->val;
        }    
           
        if(root->right)
        {
            temp_sum -= root->right->val;
            if(traversal(root->right, temp_sum)) return true;
             //否则,回溯
            temp_sum += root->right->val;
        }
        return false;
    }
public:
    //想直接在这个函数中递归调用写代码,发现判断条件和终止条件不一致
    bool hasPathSum(TreeNode* root, int targetSum) {
        if(root==NULL)  return false;
        return traversal(root,targetSum-root->val);
    }
};

113.路径总和ii

题目链接/文章讲解/视频讲解:https://programmercarl.com/0112.%E8%B7%AF%E5%BE%84%E6%80%BB%E5%92%8C.html

class Solution {
private:
    vector<vector<int>> result;
    vector<int> path;
//遍历整个二叉树,不用返回值
    void traversal(TreeNode* cur, int count){
        if(!cur->right && !cur->left && count==0)
        {
            result.push_back(path);
            return;
        }
        if(!cur->right && !cur->left)
            return;
        if(cur->left)
        {
            path.push_back(cur->left->val);
            count -= cur->left->val;
            traversal(cur->left, count);
            count+=cur->left->val;
            path.pop_back();
        }
        if(cur->right)
        {
            path.push_back(cur->right->val);
            count -= cur->right->val;
            traversal(cur->right, count);
            count+=cur->right->val;
            path.pop_back();
        }
        return;
    }
public:
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        result.clear();
        path.clear();
        if(root==NULL) return result;
        path.push_back(root->val);
        traversal(root, targetSum-root->val);
        return result;
    }
};

106.从中序与后序遍历序列构造二叉树

题目链接/文章讲解/视频讲解:https://programmercarl.com/0106.%E4%BB%8E%E4%B8%AD%E5%BA%8F%E4%B8%8E%E5%90%8E%E5%BA%8F%E9%81%8D%E5%8E%86%E5%BA%8F%E5%88%97%E6%9E%84%E9%80%A0%E4%BA%8C%E5%8F%89%E6%A0%91.html

找后序最后一个元素取出作为新二叉树的根
找到根在中序中的位置delimiterIndex,将中序划分为左右两个数组leftInorder rightInorder
将后序的最后一个元素丢弃(resize)
根据中序分割后的数组的大小来分割后序数组,得到leftPostorder rightPostorder
然后再分别将左子树、右子树的中序后序传入到traversal中

class Solution {
private:
    TreeNode* traversal(vector<int>& inorder, vector<int>& postorder)
    {
        if(postorder.size()==0) return NULL;
        int rootValue = postorder[postorder.size()-1];
        TreeNode* root = new TreeNode(rootValue);

        if(postorder.size()==1) return root;
        
        int delimiterIndex;
        for(delimiterIndex=0;delimiterIndex<inorder.size();delimiterIndex++)
        {
            if(inorder[delimiterIndex]==rootValue) break;
        }

        //切割中序
        //左闭右开
        //[0,delimiterIndex]
        vector<int> leftInorder(inorder.begin(),inorder.begin()+delimiterIndex);
        // [delimiterIndex+1,end]
        vector<int> rightInorder(inorder.begin()+delimiterIndex+1,inorder.end());
        //丢弃末尾元素
        postorder.resize(postorder.size()-1);

        // [0,delimiterIndex.size()]
        // [delimiterIndex.size(),end]
        vector<int> leftPostorder(postorder.begin(),postorder.begin()+leftInorder.size());
        vector<int> rightPostorder(postorder.begin()+leftInorder.size(),postorder.end());

        root->left = traversal(leftInorder,leftPostorder);
        root->right = traversal(rightInorder,rightPostorder);

        return root;
    }
public:
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        if(inorder.size()==0 || postorder.size()==0)
            return NULL;
        return traversal(inorder, postorder);
    }
};
  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值