【问题标题】:Regarding popping of vector elements关于向量元素的弹出
【发布时间】:2017-03-15 08:02:12
【问题描述】:

在给定二叉树和sum的情况下,以下代码用于查找等于特定sum的所有从根到叶的路径。

class Solution {
public:
    void buildResult(std::vector< std::vector< int > >& result, std::vector< int >& ans, TreeNode* root, int sum) {
        if(!root)
            return;

        ans.push_back(root->val);
        if(root->val==sum && !root->left && !root->right)
            result.push_back(ans);
        buildResult(result, ans, root->left, sum-(root->val));
        buildResult(result, ans, root->right, sum-(root->val));
        ans.pop_back();
    }

    vector<vector<int>> pathSum(TreeNode* root, int sum) {
        std::vector< vector< int > > result;
        std::vector< int > ans;

        if(!root)
            return result;

        buildResult(result, ans, root, sum);
        return result;
    }
};

上面的代码工作并生成预期的输出。但是,我不明白 ans.pop_back(); 语句的用法 - 我知道它是用于回溯,但究竟是什么时候进行的回溯?甚至在检查它们是否位于有效路径上之前,这些值就被插入到向量 ans 中。此外,pop_back()s 的数量应该很多,这取决于插入了多少导致错误总和的数字。有人可以向我解释一下这个工作吗?

谢谢!

【问题讨论】:

  • 您可以制作一个小测试用例,然后使用调试器或铅笔和纸自己看看它是如何工作的。
  • @JamesRoot,我试过了;但我无法理解。任何指针将不胜感激。

标签: c++ binary-tree


【解决方案1】:

回溯是通过递归函数返回来进行的。

递归函数在遍历树时通过将当前节点推入ans 来记录其路径。当它到达叶子时,它会检查叶子的值,如果匹配,它会记录刚刚构建的路径,方法是将ans 推入result

您可以将ans 视为指向当前节点的面包屑路径。递归函数每次进入树中的一个节点,就将当前节点的值压入ans,当到达右叶时,面包屑的尾部就是叶节点的路径。

因此,递归函数通过返回离开它正在访问的当前节点。通过从递归调用返回,递归函数返回到其父函数。但不是在从当前的面包屑尾部移除最后一个面包屑之前,恢复面包屑的踪迹以仅包含到其父级的路径,这正是它返回的位置。

【讨论】:

  • 好的,我在某种程度上明白了你的意思。假设不正确的节点顺序是0-&gt;2-&gt;5-&gt;6sum3。所以,这个节点路径不会导致正确的sum。但是,由于我们是递归工作的,我们不仅要回溯并删除最后一个元素——甚至是之前的元素(即65,两者都是)。这是如何保证的?
  • 递归调用将一次返回树的一层。请记住,当您到达最后一个节点(节点 6)时,您正处于四个递归调用的中间。当每个递归调用返回时,它会从ans 中删除最后一个面包屑。看看这有多简单?
  • 是的。我的错,我把它复杂化了。谢谢! :)
猜你喜欢
  • 2019-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-01
相关资源
最近更新 更多