题目描述
输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。
解法:利用递归的出栈顺序,来进行返回比较。详细看程序
#include <stdio.h>
#include <vector>
#include <string>
#include <stack>
#include <algorithm>
#include <iostream>
using namespace std;
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
//如何将所有路径给遍历出来?
//在遍历的时候进行选择判断,若大于number停止遍历,看是否叶节点。
//知识点:递归出栈的时候,局部变量返回之前递归调用之前的值,就如下面的currentSum,结点也是同样返回父结点
class Solution {
public:
vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
vector<int> path; //存储一次遍历的路径
vector<vector<int> > pathAll; //存储总的路径
int currentSum = 0;
if(root == NULL) return pathAll; //这个需要加上,很重要
findPathOne(pathAll, root, path, currentSum, expectNumber);
return pathAll;
}
void findPathOne(vector<vector<int> > &pathAll, TreeNode* root, vector<int> &path, int currentSum, int expectNumber) {
currentSum += root->val;
cout << currentSum;
path.push_back(root->val);
bool endRoot = (root->left == NULL) && (root->right == NULL); //判断是否为叶节点
if(endRoot && currentSum == expectNumber) pathAll.push_back(path); //为叶结点,且等于给定的值
//不为叶结点,继续递归调用,直到叶节点为止
if(root->left != NULL)
findPathOne(pathAll, root->left, path, currentSum, expectNumber);
if(root->right != NULL)
findPathOne(pathAll, root->right, path, currentSum, expectNumber);
//左子树为叶结点,递归调用结束,开始出栈,currentSum当前的值是返回前一次的结果,即出栈后的结果,根节点也返回上一个值而不是该路径的sum了
path.pop_back(); //路径左子树最后一个结点出来,继续判定右子树的递归调用,此时结点为上一层的根节点。
return;
}
};
int main() {
Solution m;
//手动建立一个二叉树用于测试
// 1
// / \
// 2 3
// / \
// 1 4
TreeNode* root = new TreeNode(1);
root->left = new TreeNode(2);
root->right = new TreeNode(3);
TreeNode* p = root->left;
p->left = new TreeNode(1);
p->right = new TreeNode(4);
int row;
int col;
vector<int> path; //存储一次遍历的路径
vector<vector<int> > pathAll; //存储总的路径
int expectNumber = 4;
pathAll = m.FindPath(root, expectNumber);
row = pathAll.size();
for(int i = 0; i < row; i++) {
for(int j = 0; j < pathAll[i].size(); j++)
cout << pathAll[i][j];
//cout << endl;
}
return 0;
}