第十九题 递归调用 解决 不断获取子树的符合要求的路径,并添加上当前结点的值
是十八题的复杂版本 不只要求判断有没有路径 要想办法 找到所有的路径并保存下来
第一个代码 稍微长一点 从根节点开始,更好理解
第二段代码是对第一个代码的化简 删除了重复的代码
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
vector<vector<int>> FindPath(TreeNode* root,int expectNumber) {
// 和上一题找结点类似
vector<vector<int>> temp;
vector<vector<int>> ret_ans;
// 两个边界情况 第二个就是 单独只有一个根节点 正好是要求的值
if(root == NULL)
return temp;
// 后面子树要的sum的和 是要求的总sum 减去当前结点的值
int sum=expectNumber-root->val;
if(sum==0 && root->left==NULL && root->right==NULL)
{
vector<int> one;
one.push_back(root->val);
ret_ans.push_back(one);
return ret_ans;
}
// 如果有左(右)孩子,就递归调用左(右)孩子
if(root->left!= NULL){
temp=find_path(root->left,sum);
ret_ans.insert(ret_ans.end(), temp.begin(),temp.end());
}
if(root->right!=NULL){
temp=find_path(root->right,sum);
ret_ans.insert(ret_ans.end(), temp.begin(),temp.end());
}
// 对返回的结果进行处理,加上当前这一层结点的值
if(!ret_ans.empty())
{
for(int i=0;i<ret_ans.size();i++)
{
ret_ans[i].push_back(root->val);
}
}
// 反转所有的结果 要求是输出从根结点开始的容器
for(int i=0;i<ret_ans.size();i++)
{
reverse(ret_ans[i].begin(),ret_ans[i].end());
}
return ret_ans;
}
// 递归调用
vector<vector<int>> find_path(TreeNode* root,int sum)
{
vector<vector<int>> ret_ans;
if(root==NULL)
return ret_ans;
sum=sum-root->val;
// 同上一题的判断条件
// 当sum成了0 并且是叶子结点,说明结果正确 返回true
if(sum==0 && root->left==NULL && root->right==NULL)
{
vector<int> oneans;
oneans.push_back(root->val);
ret_ans.push_back(oneans);
return ret_ans;
}
// temp临时保存访问子树得到的结果
vector<vector<int>> temp;
// 当不是叶子结点 则要继续往下去左右子树递归调用
// 返回的结果是左右子树 到根节点值为sum的容器,将容器保存到ret_ans中
if(root->left!=NULL){
temp=find_path(root->left,sum);
ret_ans.insert(ret_ans.end(), temp.begin(),temp.end());
}
if(root->right!=NULL){
temp=find_path(root->right,sum);
ret_ans.insert(ret_ans.end(), temp.begin(),temp.end());
}
// 如果有结果,则ret_ans要加上当前这一层的值
if(!ret_ans.empty())
{
for(int i=0;i<ret_ans.size();i++)
{
ret_ans[i].push_back(root->val);
}
}
return ret_ans;
}
};
第二个代码 化简版本
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
vector<vector<int>> FindPath(TreeNode* root,int expectNumber) {
// 和上一题找结点类似
vector<vector<int>> temp;
vector<vector<int>> ret_ans;
// 两个边界情况 第二个就是 单独只有一个根节点 正好是要求的值
if(root == NULL)
return temp;
// 后面子树要的sum的和 是要求的总sum 减去当前结点的值
int sum=expectNumber-root->val;
if(sum==0 && root->left==NULL && root->right==NULL)
{
vector<int> one;
one.push_back(root->val);
ret_ans.push_back(one);
return ret_ans;
}
// 如果有左(右)孩子,就递归调用左(右)孩子
if(root->left!= NULL){
temp=find_path(root->left,sum);
ret_ans.insert(ret_ans.end(), temp.begin(),temp.end());
}
if(root->right!=NULL){
temp=find_path(root->right,sum);
ret_ans.insert(ret_ans.end(), temp.begin(),temp.end());
}
// 对返回的结果进行处理,加上当前这一层结点的值
if(!ret_ans.empty())
{
for(int i=0;i<ret_ans.size();i++)
{
ret_ans[i].push_back(root->val);
}
}
// 反转所有的结果 要求是输出从根结点开始的容器
for(int i=0;i<ret_ans.size();i++)
{
reverse(ret_ans[i].begin(),ret_ans[i].end());
}
return ret_ans;
}
// 递归调用
vector<vector<int>> find_path(TreeNode* root,int sum)
{
vector<vector<int>> ret_ans;
if(root==NULL)
return ret_ans;
sum=sum-root->val;
// 同上一题的判断条件
// 当sum成了0 并且是叶子结点,说明结果正确 返回true
if(sum==0 && root->left==NULL && root->right==NULL)
{
vector<int> oneans;
oneans.push_back(root->val);
ret_ans.push_back(oneans);
return ret_ans;
}
// temp临时保存访问子树得到的结果
vector<vector<int>> temp;
// 当不是叶子结点 则要继续往下去左右子树递归调用
// 返回的结果是左右子树 到根节点值为sum的容器,将容器保存到ret_ans中
if(root->left!=NULL){
temp=find_path(root->left,sum);
ret_ans.insert(ret_ans.end(), temp.begin(),temp.end());
}
if(root->right!=NULL){
temp=find_path(root->right,sum);
ret_ans.insert(ret_ans.end(), temp.begin(),temp.end());
}
// 如果有结果,则ret_ans要加上当前这一层的值
if(!ret_ans.empty())
{
for(int i=0;i<ret_ans.size();i++)
{
ret_ans[i].push_back(root->val);
}
}
return ret_ans;
}
};
第二个代码 化简版本
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
vector<vector<int>> FindPath(TreeNode* root,int expectNumber) {
// 和上一题找结点类似
vector<vector<int>> temp;
vector<vector<int>> ret_ans;
// 两个边界情况 第二个就是 单独只有一个根节点 正好是要求的值
if(root == NULL)
return temp;
// 直接全部扔下去递归调用 不需要判断root有没有左右子树 而是将root直接扔下去计算
// 因为 find_path函数的代码 和之前写的判断根节点的代码完全一致
ret_ans=find_path(root, expectNumber);
// 反转所有的结果 要求是输出从根结点开始的容器
for(int i=0;i<ret_ans.size();i++)
reverse(ret_ans[i].begin(),ret_ans[i].end());
return ret_ans;
}
// 递归调用
vector<vector<int>> find_path(TreeNode* root,int sum)
{
vector<vector<int>> ret_ans;
if(root==NULL)
return ret_ans;
sum=sum-root->val;
// 同上一题的判断条件
// 当sum成了0 并且是叶子结点,说明结果正确 将这个结点 装入一维数组 添加到ret_ans中
// 后面 收到的结果 在这个结点之上,继续补充路径上的val
if(sum==0 && root->left==NULL && root->right==NULL){
vector<int> oneans;
oneans.push_back(root->val);
ret_ans.push_back(oneans);
return ret_ans;
}
// temp临时保存访问子树得到的结果
vector<vector<int>> temp;
// 当不是叶子结点 且还有左(右)子树,则要继续往下去递归调用左右子树
// 返回的结果是左右子树 到根节点值为sum的容器,将容器保存到ret_ans中
if(root->left!=NULL){
temp=find_path(root->left,sum);
ret_ans.insert(ret_ans.end(), temp.begin(),temp.end());
}
if(root->right!=NULL){
temp=find_path(root->right,sum);
ret_ans.insert(ret_ans.end(), temp.begin(),temp.end());
}
// 如果有结果,则ret_ans要加上当前这一层的值
if(!ret_ans.empty())
for(int i=0;i<ret_ans.size();i++)
ret_ans[i].push_back(root->val);
return ret_ans;
}
};
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
vector<vector<int>> FindPath(TreeNode* root,int expectNumber) {
// 和上一题找结点类似
vector<vector<int>> temp;
vector<vector<int>> ret_ans;
// 两个边界情况 第二个就是 单独只有一个根节点 正好是要求的值
if(root == NULL)
return temp;
// 直接全部扔下去递归调用 不需要判断root有没有左右子树 而是将root直接扔下去计算
// 因为 find_path函数的代码 和之前写的判断根节点的代码完全一致
ret_ans=find_path(root, expectNumber);
// 反转所有的结果 要求是输出从根结点开始的容器
for(int i=0;i<ret_ans.size();i++)
reverse(ret_ans[i].begin(),ret_ans[i].end());
return ret_ans;
}
// 递归调用
vector<vector<int>> find_path(TreeNode* root,int sum)
{
vector<vector<int>> ret_ans;
if(root==NULL)
return ret_ans;
sum=sum-root->val;
// 同上一题的判断条件
// 当sum成了0 并且是叶子结点,说明结果正确 将这个结点 装入一维数组 添加到ret_ans中
// 后面 收到的结果 在这个结点之上,继续补充路径上的val
if(sum==0 && root->left==NULL && root->right==NULL){
vector<int> oneans;
oneans.push_back(root->val);
ret_ans.push_back(oneans);
return ret_ans;
}
// temp临时保存访问子树得到的结果
vector<vector<int>> temp;
// 当不是叶子结点 且还有左(右)子树,则要继续往下去递归调用左右子树
// 返回的结果是左右子树 到根节点值为sum的容器,将容器保存到ret_ans中
if(root->left!=NULL){
temp=find_path(root->left,sum);
ret_ans.insert(ret_ans.end(), temp.begin(),temp.end());
}
if(root->right!=NULL){
temp=find_path(root->right,sum);
ret_ans.insert(ret_ans.end(), temp.begin(),temp.end());
}
// 如果有结果,则ret_ans要加上当前这一层的值
if(!ret_ans.empty())
for(int i=0;i<ret_ans.size();i++)
ret_ans[i].push_back(root->val);
return ret_ans;
}
};