力扣第15天----第513题、第112、113题、第106题

力扣第15天----第513题、第112、113题、第106、105题

一、第513题–找树左下角的值

​ 大概明白了吧,重点在于回溯的运用。这里采用后序遍历(前序遍历、中序遍历都可以)。定义几个全局变量,通过travesal函数不断递归遍历二叉树,去修改全局变量。

  • 传入参数及返回值----要遍历的根节点,所处的深度。这里要用到了回溯,遍历的时候加1,遍历完了返回给上一层节点时,减1。
  • 终止条件----当前root处于叶子节点就返回。返回前要修改maxdepth、result数值,如果当前节点depth大于maxdepth,maxdepth就+1;result就赋值为root的val。因为一层中只有最左侧会触发“当前节点depth大于maxdepth”条件,所以result就记录了最左侧的值。
  • 单层递归逻辑----遍历左子树,遍历右子树,注意depth回溯。遍历子树完成后,要恢复原状,回到根节点状态,不能影响其他子树的遍历。
class Solution {
public:
    int result;
    int maxdepth = 1;
    void travesal(TreeNode* root, int depth){
        if (root->left == nullptr && root->right == nullptr){
            if (depth > maxdepth){
                result = root->val;
                maxdepth = depth;
            } 
            return;
        }
        if(root->left){
            depth++;
            travesal(root->left, depth);
            depth--;
        }
        if (root->right){
            depth++;
            travesal(root->right, depth);
            depth--;
        }
    }

    int findBottomLeftValue(TreeNode* root) {
        result = root->val;
        travesal(root, 1);
        return result;
    }
};

二、第112、113题–路径总和

​ 112题,采用后序遍历,其实对于中节点,没有处理。

  • 传入参数及返回值—如果要维护全局变量,就要重新定义递归函数,有时候用全局变量会逻辑清晰、操作简单,譬如有vector这种不易操作的,就额外使用全局变量,再定义一个新函数。这道题不需要全局变量,不用重新定义函数。
class Solution {
public:
    bool hasPathSum(TreeNode* root, int targetSum) {
        if (root == nullptr) return false;
        if (root->left == nullptr && root->right == nullptr && root->val == targetSum) return true;
        if (root->left == nullptr && root->right == nullptr && root->val != targetSum) return false;
        if (hasPathSum(root->left, targetSum - root->val)) return true;
        if (hasPathSum(root->right, targetSum - root->val)) return true;
        return false;
    }
};

​ 113题,跟上面一道题,不太一样,费了点劲。

class Solution {
public:
    vector<vector<int>> result;
    vector<int> r;
    void dfs(TreeNode* root, int targetSum){
        if (root == nullptr) return ;
        r.push_back(root->val);
        if (root->left == nullptr && root->right == nullptr && root->val == targetSum){
            result.push_back(r);
        }
        dfs(root->left, targetSum - root->val);
        dfs(root->right, targetSum - root->val);        
        r.pop_back();
    }
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        dfs(root, targetSum);
        return result;
    }
};

三、第106、105题-- 从中序与后序遍历序列构造二叉树

​ 106题,实现时很麻烦,要很小心、很注意。思路:后序遍历找中节点,并建立跟节点root→前序遍历找中节点index→前序遍历拆分左右子树→后续遍历拆分左右子树(根据前序左子树的大小)→递归实现,左右子树的构建(返回子树的根节点)→root的left、right分别指向左右子树的根节点。

class Solution {
public:
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        if (inorder.size() == 0) return nullptr;
        int center_val = postorder[postorder.size() - 1];
        int center_index = 0;
        for (int i = 0; i < inorder.size(); i++){
            if (inorder[i] == center_val) center_index = i;
        }
        TreeNode* root = new TreeNode(center_val);

        vector<int> inorder_left(inorder.begin() , inorder.begin() + center_index );
       // for_each(inorder_left.begin(), inorder_left.end(), [](int i){cout <<i << ' ';});
       // cout << endl;

        vector<int> inorder_right(inorder.begin()+center_index+1 , inorder.end());
       // for_each(inorder_right.begin(), inorder_right.end(), [](int i){cout <<i << ' ';});
       // cout << endl;

        vector<int> postorder_left(postorder.begin(), postorder.begin() + inorder_left.size());
       // for_each(postorder_left.begin(), postorder_left.end(), [](int i){cout <<i << ' ';});
       // cout << endl;

        vector<int> postorder_right(postorder.begin() + inorder_left.size(), postorder.end() - 1);
       // for_each(postorder_right.begin(), postorder_right.end(), [](int i){cout <<i << ' ';});
       // cout << endl;

        TreeNode* left = buildTree(inorder_left, postorder_left);
        TreeNode* right = buildTree(inorder_right, postorder_right);
        
        root->left = left;
        root->right = right;

        return root;
    }
};

​ 105题,跟106题,基本上一模一样的。

class Solution {
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        if (inorder.size() == 0) return nullptr;
        int center_val = preorder[0];
        int center_index = 0;
        for (int i = 0; i < inorder.size(); i++){
            if (inorder[i] == center_val) center_index = i;
        }
        TreeNode* root = new TreeNode(center_val);

        vector<int> inorder_left(inorder.begin() , inorder.begin() + center_index );
        //for_each(inorder_left.begin(), inorder_left.end(), [](int i){cout <<i << ' ';});
        //cout << endl;

        vector<int> inorder_right(inorder.begin()+center_index+1 , inorder.end());
        //for_each(inorder_right.begin(), inorder_right.end(), [](int i){cout <<i << ' ';});
        //cout << endl;

        vector<int> preorder_left(preorder.begin()+1, preorder.begin() +1 +inorder_left.size());
       // for_each(preorder_left.begin(), preorder_left.end(), [](int i){cout <<i << ' ';});
       // cout << endl;

        vector<int> preorder_right(preorder.begin()  +1 +inorder_left.size(), preorder.end()) ;
       // for_each(preorder_right.begin(), preorder_right.end(), [](int i){cout <<i << ' ';});
      //  cout << endl;

        TreeNode* left = buildTree(preorder_left, inorder_left);
        TreeNode* right = buildTree(preorder_right, inorder_right);
        
        root->left = left;
        root->right = right;

        return root;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值