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

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

LeetCode 513.找树左下角的值

题目链接:LeetCode 513.找树左下角的值

思路:
递归法,即寻找最左的节点。先找左节点,一定是最左边的。
迭代法,理解清晰,记录最左节点。

//递归法
class Solution {
public:
    int maxDepth = -1;
    int result;

    void traversal(TreeNode* node, int depth){
        if (!node) return;
        if(depth > maxDepth){
            maxDepth = depth;
            result = node->val;
        }
        if(node->left) traversal(node->left, depth+1);
        if(node->right) traversal(node->right, depth+1);
    }
    int findBottomLeftValue(TreeNode* root) {
        traversal(root, 0);
        return result;
    }
};

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

注意 :

  1. maxDepth为全局变量

LeetCode 112. 路径总和

题目链接:LeetCode 112. 路径总和

思路:
递归法,简单。

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

LeetCode 113.路径总和ii

题目链接:LeetCode 113.路径总和ii

思路:
1.思路类似,简单。 递归法,注意回溯过程。

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

注意 :

  1. path为指针,需pop
  2. count传值,不需要减掉

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

题目链接:LeetCode 106.从中序与后序遍历序列构造二叉树

思路:
1.先用后序确定root,再切分中序,最后切分后序。

class Solution {
public:

    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        if(!postorder.size()) return NULL;

        int rootValue = postorder[postorder.size()-1];
        TreeNode* root = new TreeNode(rootValue);

        if(inorder.size()==1) return root;
        
        auto it = find(inorder.begin(),inorder.end(), rootValue);
        int cut = it-inorder.begin();

        vector<int> leftInorder(inorder.begin(),inorder.begin()+cut);
        vector<int> rightInorder(inorder.begin()+cut+1,inorder.end());

        postorder.pop_back();

        vector<int> leftPostorder(postorder.begin(),postorder.begin()+leftInorder.size());
        vector<int> rightPostorder(postorder.begin()+leftInorder.size(),postorder.end());

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

        return root;
    }
};

注意 :

  1. 每次后序切分时注意弹出最后一个元素。

LeetCode 105.从前序与中序遍历序列构造二叉树

题目链接:LeetCode 105.从前序与中序遍历序列构造二叉树

思路:
同105

class Solution {
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        if(!preorder.size()) return NULL;
        int rootValue = preorder[0];
        TreeNode* root = new TreeNode(rootValue);

        if(preorder.size()==1) return root;
        int cut = 0;
        for(; cut<inorder.size();cut++) if(inorder[cut]==rootValue) break;

        vector<int> leftInorder(inorder.begin(), inorder.begin()+cut);
        vector<int> rightInorder(inorder.begin()+cut+1, inorder.end());
        
        preorder.erase(preorder.begin());

        vector<int> leftPreorder(preorder.begin(), preorder.begin()+cut);
        vector<int> rightPreorder(preorder.begin()+cut, preorder.end());

        root->left = buildTree(leftPreorder, leftInorder);
        root->right = buildTree(rightPreorder, rightInorder);

        return root;
    }
};

注意 :

  1. 前序的删除首元素,用erase。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值