剑指 Offer 34. 二叉树中和为某一值的路径
个人思路
题意
思路
此题的子集属于排列树
- 递归参数:当前的根节点root,目标sum,当前累加数字cur
- 递归出口:当根节点为空时,直接return
- 递归体:将root中的数据加入temp,进行累加,判断是否满足sum,递归访问左右子树(撤销选择的细节问题见下方)
-
- 剪枝判断:如果cur == sum 且当前节点为叶子节点,则进行存储输出(return的细节问题见下方)
注意
- 为什么要撤销选择?撤销操作其实是用vector模拟栈: 如果我们遍历到一条路径的叶节点了,然后需要切换到下一条路径的叶节点(比如题目示例中,我们遍历完了 5-4-11-7,现在要从 7 切换到 右边的 2),我们需要先从 temp 中把 7 pop_back。这样才能保证切换了之后,temp里的值会是:5,4,11,2;而不是:5,4,11,7,2。
- 为什么不需要撤销cur? 因为我们这里用的是递归,也就是当递归到头的时候会回溯。所以sum和temp不同,temp是只有一个,每次递归都是直接在操作(改变)temp里的值;但是sum是每次递归都有自己的sum,所以递归到头,回溯到上一级,sum指的是上一级的sum。故不需要对sum做操作。可能有一点绕,但是意思其实就是:temp只有一个,sum则是每次递归都有自己的sum
- 递归出口中return的作用,何时要return,return的注意事项: return可以终止当前这一层的递归,如果在递归出口中使用return,递归出口下方的所有语句将不再执行,包括之后的撤销语句。因此如果写return语句,则在return之前需要先temp.pop_back(),以撤销选择
- 递归出口中暂存的数据temp何时要清空? :根据题意来定,因为二叉树的回溯时只是需要遍历分叉位置之后的分支,而分叉位置之前的数据不需要清空
个人思路代码
错误代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int> > vec;
vector<int> temp;
void getSum(TreeNode* root, int sum, int cur){
if(root == NULL){
if(cur == sum){
// cout << "****" << endl;
vec.push_back(temp);
}
cout << cur << endl;
temp.clear();//问题一
return;//问题二
}
temp.push_back(root->val);//问题三
cur += root->val;
getSum(root->left, sum, cur);
getSum(root->right, sum, cur);
temp.pop_back();
cur -= root->val;//问题四
}
vector<vector<int>> pathSum(TreeNode* root, int sum) {
getSum(root, sum, 0);
return vec;
}
};
正确代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int> > vec;
vector<int> temp;
void getSum(TreeNode* root, int sum, int cur){
if(root == NULL)//空节点
return;
temp.push_back(root->val);
cur += root->val;
if(cur == sum && root->left == NULL && root->right == NULL){//判断是否等于sum,且是否走到了叶子节点
vec.push_back(temp);
temp.pop_back();
return;
}
getSum(root->left, sum, cur);
getSum(root->right, sum, cur);
temp.pop_back();
}
vector<vector<int>> pathSum(TreeNode* root, int sum) {
getSum(root, sum, 0);
return vec;
}
};