c++递归函数的参数为STL容器引用时的使用注意事项

当容器作为函数的参数时,假设函数为run(vector<int> nums),nums是一个对象,此时为复制构造函数构造参数nums,如果为run(vector<int> &nums),此时则是对象引用,是直接在操作要传递进来的实参对象,与run(vector<int *> nums),直接*nums是一样的,在函数内部修改nums的内容会直接影响到外部的实参。因此,当函数为递归函数时,在回溯时需要注意对象(非基本类型)参数类型是否为引用。
下面举一个例子:

257. 二叉树的所有路径

给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。

叶子节点 是指没有子节点的节点。

示例 1:

输入:root = [1,2,3,null,5]
输出:["1->2->5","1->3"]

示例 2:

输入:root = [1]
输出:["1"]

提示:

  • 树中节点的数目在范围 [1, 100]
  • -100 <= Node.val <= 100

解题思路:
求所有路径,我们想到可以用二叉树遍历,
采用递归方法进行前序遍历,遍历到叶子节点时,使用容器vector<string>存储路径,同时我们还需要一个vector<int>去记录当前节点的路径,在找到叶子节点时要把这个路径存储到容器中去,最后递归时需要传入根结点。所以我们可以得出函数参数为(vector<string> result,vector<int> cur_path,TreeNode *root)。
然后思考下,result,cur_path这两个容器是否需要加&,首先是result,若不加引用,则无法改变外部实参,最后外部的实参结果为空容器,因此必须加上,或者传入指针;接着看cur_path,作用是存储当前路径,每次遍历到一个节点时,就把当前节点的val加入容器中去,遍历到叶子节点时,就把整个路径存储到result中去,同时递归函数返回到上一个节点,此时若是加了&,则cur_path中存储着叶子节点的值,这是我们不希望的,因为当前路径已经不在叶子节点处结尾了,因此在递归函数返回时,需要去除去掉cur_path的末尾节点,而此时如果我们不加&,递归函数返回时,当前的cur_path没有变化,之前上一层传入的是cur_path的复制体,不管之前的cur_path如何变化,都不会影响此时的cur_path。
所以我们在考虑递归函数的参数时,若为stl容器或者对象时,需要认真考虑递归函数返回的情况,是否需要使用&,使用和不使用的处理方式是不一样的,下面给出两种方式的代码。
void travalsal(TreeNode *root,vector<string> &result,vector<int> cur);cur不使用&。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    void travalsal(TreeNode *root,vector<string> &result,vector<int> cur)
    {
        cur.push_back(root->val);
        if(root->left == nullptr && root->right == nullptr)
        {
            string temp;
            for(int i = 0;i < cur.size();i++)
            {
                temp += std::to_string(cur[i]);
                if(i == cur.size()-1)
                    break;
                 temp += "->";
            }
            cout << temp << endl;
            result.push_back(temp);
            return;
        }

        if(root->left)
        {
            travalsal(root->left,result,cur);
        }
        if(root->right)
        {
            travalsal(root->right,result,cur);
        }
        return;
    }
    vector<string> binaryTreePaths(TreeNode* root) {
        vector<string> result;
            if(root == nullptr)
                return result;
            vector<int> path;
            travalsal(root,result,path);
            return result;
    }
};

void travalsal(TreeNode *root,vector<string> &result,vector<int> &cur);cur使用&。
注意在递归函数(travalsal())返回后,删除掉末尾在root->right或者root->left里面添加的节点。

class Solution {
public:
    void travalsal(TreeNode *root,vector<string> &result,vector<int> &cur)
    {
        cur.push_back(root->val);
        if(root->left == nullptr && root->right == nullptr)
        {
            string temp;
            for(int i = 0;i < cur.size();i++)
            {
                temp += std::to_string(cur[i]);
                if(i == cur.size()-1)
                    break;
                 temp += "->";
            }
            cout << temp << endl;
            result.push_back(temp);
            return;
        }

        if(root->left)
        {
            travalsal(root->left,result,cur);
            cur.pop_back();
        }
        if(root->right)
        {
            travalsal(root->right,result,cur);
            cur.pop_back();
        }
        cout << root->val << " " << result.size();
        return;
    }
    vector<string> binaryTreePaths(TreeNode* root) {
        vector<string> result;
            if(root == nullptr)
                return result;
            vector<int> path;
            travalsal(root,result,path);
            return result;
    }
};

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值