两种解法效率对比:
我的解法:效率较低
思想:
●遇到叶子节点判断是否为0,不为0则返回,为0则将路径加入res
●不为叶子节点,递归访问子节点。
注意:
注意path是值传递,引用传递的话不同路径会互相干扰
效率较低:
每一层递归都要创建一个临时的vector
class Solution {
private:
vector<vector<int>>res;
public:
vector<vector<int>> pathSum(TreeNode* root, int sum) {
pathSum_helper(root, sum, {
});
return res;
}
//注意path是值传递,引用传递的话不同路径会互相干扰
void pathSum_helper(TreeNode* root, int sum, vector<int>path){
//为空则直接返回
if(root == NULL)
return;
//将当前节点值放入路径
path.push_back(root->val);
//如果为叶子节点,值相等则将路径插入res,不等则返回
if(root->left == NULL && root->right == NULL){
if(sum == root->val)
res.push_back(path);
//可加可不加,因为下面递归中直接root == NULL就return了,但是回溯中不能加
else
return;
}
pathSum_helper(root->left, sum - root->val, path);
pathSum_helper(root->right, sum - root->val, path);
}
};
改进解法:回溯
思想:
注意,如果我们遍历到一条路径的叶节点了,然后需要切换到下一条路径的叶节点(比如题目示例中,我们遍历完了 5-4-11-7,现在要从 7 切换到 右边的 2),我们需要先从 temp 中把 7 pop_back。这样才能保证切换了之后,temp里的值会是:5,4,11,2;而不是:5,4,11,7,2。
与上面区别:
●path为引用传递,引用传递加回溯可以让每条路径互不干扰
●如果到底发现值不相同,不能返回,因为还要回溯
●调用完递归要回溯,弹出当前节点
class Solution {
private:
vector<vector<int>>res;
public:
vector<vector<int>> pathSum(TreeNode* root, int sum) {
vector<int>path;
pathSum_helper(root, sum, path);
return res;
}
void pathSum_helper(TreeNode* root, int sum, vector<int>&path){
//为空则直接返回
if(root == NULL)
return;
//将当前节点值放入路径
path.push_back(root->val);
//如果为叶子节点,值相等则将路径插入res,不等则返回
if(root->left == NULL && root->right == NULL){
if(sum == root->val)
res.push_back(path);
/*
回溯法就不能加了,因为还可以回溯,不能直接返回
else
return;
*/
}
pathSum_helper(root->left, sum - root->val, path);
pathSum_helper(root->right, sum - root->val, path);
//回溯
path.pop_back();
}
};