代码随想录算法训练营Day18 | LeetCode513找树左下角的值、 LeetCode112/113路径总和、LeetCode105/106从中序与后序遍历序列构造二叉树

LeetCode513找树左下角的值

本题利用迭代法层序遍历二叉树非常简单,只需要记录最后一行的第一个元素即可,代码如下:

class Solution {
public:
    int findBottomLeftValue(TreeNode* root) {
        if(root==nullptr) return 0;
        queue<TreeNode*> que;
        que.push(root);
        int result = 0;
        while(!que.empty()){
            int size = que.size();
            for(int i=0;i<size;i++){
                TreeNode* tmp = que.front();
                que.pop();
                if(i==0) result = tmp->val;
                if(tmp->left) que.push(tmp->left);
                if(tmp->right) que.push(tmp->right);
            }
        }
        return result;
    }
};

比较难的是使用递归的方法,递归的思路为找到最开始的最大深度的节点,因为不管使用什么遍历,左节点始终在右节点前面,所以最开始找到的最大深度的节点即为最后一行的最左边节点,思路还是挺巧妙的,这道题也不用处理中间节点,代码如下:

递归的过程可以用traversal(node->left,depth+1)代替,这个过程就隐含了回溯的过程

class Solution {
public:
    int maxDepth = INT_MIN;
    int result = 0;
    void traversal(TreeNode* node,int depth){
        if(!node->left && !node->right){
            if(depth>maxDepth){
                result = node->val;
                maxDepth = depth;
            }
        }
        if(node->left){
            depth++;
            traversal(node->left,depth);
            depth--;
        }
        if(node->right){
            depth++;
            traversal(node->right,depth);
            depth--;
        }
    }
    int findBottomLeftValue(TreeNode* root) {
        //递归
        traversal(root,0);
        return this->result;

    }
};

LeetCode112/113路径总和

递归思路

注意两点:1、traversal的返回值是bool类型,如果遇到true条件,则一层层向上返回true
2、注意回溯迭代过程

class Solution {
public:
    bool traversal(TreeNode* node,int count){
        if(!node->left && !node->right && count==0){
            return true;
        }
        if(!node->left && !node->right) return false;
        if(node->left){
            count -= node->left->val;
            if(traversal(node->left,count)) return true;
            count += node->left->val;
        }
        if(node->right){
            count -= node->right->val;
            if(traversal(node->right,count)) return true;
            count += node->right->val;
        }
        return false;
    }
    bool hasPathSum(TreeNode* root, int targetSum) {
        if(root==nullptr) return false;
        if(traversal(root,targetSum-root->val)) return true;
        return false;
    }
};

迭代思路:层序遍历每一个结点的时候,记录当下target-该节点的val值,需要存入一个pair变量

113题递归思路稍作修改即可,代码如下:

class Solution {
public:
    vector<vector<int>> res;
    vector<int> path;
    void traversal(TreeNode* node,int count){
        if(!node->left && !node->right && count==0){
            res.push_back(path);
        }
        if(node->left){
            count -= node->left->val;
            path.push_back(node->left->val);
            traversal(node->left,count);
            path.pop_back();
            count += node->left->val;
        }
        if(node->right){
            count -= node->right->val;
            path.push_back(node->right->val);
            traversal(node->right,count);
            path.pop_back();
            count += node->right->val;
        }
    }
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        res.clear();
        if(root==nullptr) return res;
        path.clear();
        path.push_back(root->val);
        traversal(root,targetSum-root->val);
        return res;
    }
};

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

106从中序与后序构造二叉树,思路如下:

1、后序为空,返回null
2、寻找根节点(后序的末尾)
3、根据根节点寻找中序中根节点的位置
4、将中序切割为左子树的中序和右子树的前序
5、将后序切割为左子树的后序和右子树的后序
6、递归处理左区间右区间

这里切割后序时根据中序左右子树的大小来判断,代码如下:

class Solution {
public:
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        if(postorder.empty()) return nullptr;
        int rootNum = postorder[postorder.size()-1];
        TreeNode* root = new TreeNode(rootNum);
        if(postorder.size()==1) return root;
        int index;
        for(index=0;index<inorder.size();index++){
            if(inorder[index]==rootNum) break;
        }
        vector<int> leftInorder(inorder.begin(),inorder.begin()+index);
        vector<int> leftPostorder(postorder.begin(),postorder.begin()+index);

        vector<int> rightInorder(inorder.begin()+index+1,inorder.end());
        vector<int> rightPostorder(postorder.begin()+index,postorder.end()-1);
        root->left = buildTree(leftInorder,leftPostorder);
        root->right = buildTree(rightInorder,rightPostorder);
        return root;
    }
};

105利用中序和前序构造二叉树,思路类似,代码如下:

class Solution {
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        if(preorder.empty()) return nullptr;
        int rootNum = preorder[0];
        TreeNode* root = new TreeNode(rootNum);
        if(preorder.size()==1) return root;
        int index;
        for(index=0;index<inorder.size();index++){
            if(inorder[index]==rootNum) break;
        }
        vector<int> leftPreorder(preorder.begin()+1,preorder.begin()+index+1);
        vector<int> leftInorder(inorder.begin(),inorder.begin()+index);

        vector<int> rightPreorder(preorder.begin()+index+1,preorder.end());
        vector<int> rightInorder(inorder.begin()+index+1,inorder.end());
        root->left = buildTree(leftPreorder,leftInorder);
        root->right = buildTree(rightPreorder,rightInorder);
        return root;
    }
};

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值