代码随想录算法训练营第18天|513 112 113 106 105

513 层序遍历注意先放右边再放左边 这样queue里面最后一个数才是要找的

递归法 还是要多练习 找终止条件已经终止后处理方式是最重要的,这里终止条件即子叶,再加判断此时是否在最深处,如果是,更新maxDepth和result。

1.我用了隐藏回溯,隐藏回溯其实就是不要改变传递的值在本函数的值 但是传参的时候又对应更新了。(这里是传depth)

2.这里是先左后右,因为到子叶的时候maxDepth已经被更新了 判断条件是depth>maxDepth。没有等于号 所以同深度的右边叶子不会刷新数值,跟迭代会刷新不一样。

3.maxDepth在这边传递的时候要用&,不然会出bug。解释如下:(但我还是没太看明白为什么)

(cr to chatGPT)

在你的代码中,`depth` 参数并没有像 `maxDepth` 那样在函数内部被修改并期望这个修改能反映到函数外部。当你对 `depth` 参数进行加法运算并将结果传递给下一级的 `traversal` 函数调用时,你实际上创建了一个新的 `depth` 值。原始的 `depth` 值并没有被改变,你只是基于它计算出了一个新的值并传递给了下一级的函数调用。

在你的 `traversal` 函数中,`depth` 参数在每一级的函数调用中都是独立的。对于任何特定的函数调用,`depth` 参数只代表从根节点到当前节点的深度,它并不需要被修改并反映到函数外部。因此,你可以按值传递 `depth` 参数,而不需要像 `maxDepth` 和 `result` 那样按引用传递。

请注意,按值传递和按引用传递在C++中是非常重要的概念,理解它们之间的差别对于写出正确的C++代码是至关重要的。

/*  //层序遍历
class Solution {
public:
    int findBottomLeftValue(TreeNode* root) {
        queue<TreeNode*>que;
        int result;
        if (root!=nullptr) que.push(root);
        
        while (!que.empty()) {
            TreeNode* curr = que.front();
            result = curr->val;
            que.pop();
            if (curr->right) que.push(curr->right);
            if (curr->left) que.push(curr->left);
        }
        return result;
    }
}; */

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

112 

/* //递归
class Solution {
    void traversal(TreeNode* root, int& remain, bool& found) {
        remain-=root->val;
        if (root->left==nullptr && root->right == nullptr) {
            if (remain==0) {
                found = true;
            }
            return;
        }
        if (root->left) {
            traversal(root->left, remain, found);
            remain+=root->left->val;
        }
        if (root->right) {
            traversal(root->right, remain, found);
            remain+=root->right->val;
        }
    }
public:
    bool hasPathSum(TreeNode* root, int targetSum) {
        if (root==nullptr) return false;
        bool found = false;
        traversal(root, targetSum, found);
        return found;
    }
}; */
//简化之后

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


//迭代
class Solution {
public:
    bool hasPathSum(TreeNode* root, int targetSum) {
        stack<pair<TreeNode*, int>> stack; 
        if (root!=nullptr) {
            pair<TreeNode*, int> p;
            p.first = root;
            p.second = root->val;
            stack.push(p);
        }
        while (!stack.empty()) {
            pair<TreeNode*, int> curr_p = stack.top();
            if (curr_p.first->left==nullptr && curr_p.first->right==nullptr && curr_p.second==targetSum) return true; 
            stack.pop();
            if (curr_p.first->left!=nullptr) {
                pair<TreeNode*, int> left;
                left.first=curr_p.first->left;
                left.second=curr_p.second+left.first->val;
                stack.push(left);
            }
            if (curr_p.first->right!=nullptr) {
                pair<TreeNode*, int> right;
                right.first=curr_p.first->right;
                right.first=curr_p.first->right;
                right.second=curr_p.second+right.first->val;
                stack.push(right);
            }
        }
        return false;
    }
};

113

 //递归
class Solution {
    vector<vector<int>> paths;
    void traversal (TreeNode* root, int sum, vector<int>& path) {
        if (!root->left && !root->right && root->val == sum) {
            path.push_back(root->val);
            paths.push_back(path);
            path.pop_back();
            return;
        }
        if (root->left) {
            path.push_back(root->val);
            traversal(root->left, sum-root->val, path);
            path.pop_back();
        }
        if (root->right) {
            path.push_back(root->val);
            traversal(root->right, sum-root->val, path);
            path.pop_back();
        }
    }
public:
    vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
        if (root==nullptr) return paths;
        vector<int> path;
        traversal(root, targetSum, path);
        return paths;
    }
};

106

class Solution {
    TreeNode* traversal(vector<int>& inorder, vector<int>& postorder) {
        if (inorder.size()==0)  return nullptr;
        
        int val = postorder[postorder.size()-1];
        vector<int> left_inorder;
        int i;
        for (i=0; i<inorder.size(); i++) {
            if (inorder[i]==val){
                break;
            }
            left_inorder.push_back(inorder[i]);
        }
        vector<int> right_inorder;
        right_inorder.insert(right_inorder.end(), inorder.begin()+i+1, inorder.end());
        vector<int> left_postorder;
        left_postorder.insert(left_postorder.end(), postorder.begin(), postorder.begin()+i);
        vector<int> right_postorder;
        right_postorder.insert(right_postorder.end(), postorder.begin()+i, postorder.end()-1);

        TreeNode* root = new TreeNode(val);
        root->left = traversal(left_inorder, left_postorder);
        root->right = traversal(right_inorder, right_postorder);
        return root;
    }
public:
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
        return traversal(inorder, postorder);
    }
};

cr to 代码随想录 ,这种定义vector的方式比我简单,要学习。我用的是insert。 都是左闭右开。

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

105 递归的时候传递头尾的index,这样可以节约空间,不用每次递归都新建两个vector

class Solution {
    TreeNode* traversal(vector<int>& preorder, vector<int>& inorder, int pre_s, int pre_e, int in_s, int in_e){
        if (pre_e-pre_s==0) return nullptr;
        int val = preorder[pre_s];
        int index;
        for (index=0; index<in_e-in_s; index++){
            if (inorder[index+in_s]==val) break;
        }
        //用左闭右开
        
        TreeNode* root = new TreeNode(val);
        root->left = traversal(preorder, inorder, pre_s+1, pre_s+index+1, in_s, in_s+index);
        root->right = traversal(preorder, inorder, pre_s+index+1, pre_e, in_s+index+1, in_e);
        return root;
    }
public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        return traversal(preorder, inorder, 0, preorder.size(), 0, inorder.size());
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
代码随想录算法训练是一个优质的学习和讨论平台,提供了丰富的算法训练内容和讨论交流机会。在训练中,学员们可以通过观看视频讲解来学习算法知识,并根据讲解内容进行刷题练习。此外,训练还提供了刷题建议,例如先看视频、了解自己所使用的编程语言、使用日志等方法来提高刷题效果和语言掌握程度。 训练中的讨论内容非常丰富,涵盖了各种算法知识点和解题方法。例如,在第14天的训练中,讲解了二叉树的理论基础、递归遍历、迭代遍历和统一遍历的内容。此外,在讨论中还分享了相关的博客文章和配图,帮助学员更好地理解和掌握二叉树的遍历方法。 训练还提供了每日的讨论知识点,例如在第15天的讨论中,介绍了层序遍历的方法和使用队列来模拟一层一层遍历的效果。在第16天的讨论中,重点讨论了如何进行调试(debug)的方法,认为掌握调试技巧可以帮助学员更好地解决问题和写出正确的算法代码。 总之,代码随想录算法训练是一个提供优质学习和讨论环境的平台,可以帮助学员系统地学习算法知识,并提供了丰富的讨论内容和刷题建议来提高算法编程能力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [代码随想录算法训练每日精华](https://blog.csdn.net/weixin_38556197/article/details/128462133)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值