相信大家在写递归的时候都会遇到几个问题
如何回溯到上一步,回溯到上一步走过的代码是否会产生影响作用
举例
class Solution {
public:
vector<TreeNode*>path_p;
vector<TreeNode*>path_q;
void get(TreeNode*root,TreeNode*target,vector<TreeNode*>&path,vector<TreeNode*>paths)
{
if(root==NULL) return;
paths.push_back(root);
if(root!=target)
{
get(root->left,target,path,paths);
get(root->right,target,path,paths);
}
else{
path=paths;
}
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
vector<TreeNode*>a;
get(root,p,path_p,a);
get(root,q,path_q,a);
TreeNode*ancestor;
for(int i=0;i<path_p.size()&&i<path_q.size();i++)
{
if(path_p[i]==path_q[i])
ancestor=path_p[i];
}
return ancestor;
}
};
这个是leetcode中关于二叉树最近祖先的问题,其中的第一个代码块解决的是寻找路径问题并且将路径节点保存如数组。
仔细看,第一个代码中有两个参量,一个是带了引用的path,一个是不带引用的paths。他们的作用是什么呢。
当不带引用的时候,进入代码块也就不会改变他的状态,也就是说,当这条路没找到节点的时候,是可以回溯到当前地方的,而不用pop_back()将存入数组的节点再删掉,因为引用不会改变回溯到目前位置的状态。而如果加上&也就是说进入的每一次递归都会根本改变数组的成分。而带了引用的参数只是为了保存现在的路径。其实也可以用一个全局变量存储。
也就是说,当在写递归的时候,参数是否使用引用直接决定了参数的结果,要谨慎。