二叉树中和为某一值的路径
- 参与人数:2929时间限制:1秒空间限制:32768K
- 算法知识视频讲解
题目描述
输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。
牛客网不给测试用例让我感到很迷惑啊。。再次提醒自己,vector是否为空用vector.empty()判断!
// 24.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <vector>
using namespace::std;
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 exp) {
vector<vector<int>> retVec;
if (root == NULL)return retVec;
vector<int> path;
int cur = 0;
recursive(root, retVec, path, exp, cur);
return retVec;
}
void recursive(TreeNode* root, vector<vector<int>>& retVec, vector<int>& path, int sum, int& cur) {
path.push_back(root->val);
cur = cur + root->val;
bool isLeaf = (root->left == NULL) && (root->right == NULL);
if (isLeaf && sum == cur) {
retVec.push_back(path);
}
if (root->left != NULL) {
recursive(root->left, retVec, path, sum, cur);
}
if (root->right != NULL) {
recursive(root->right, retVec, path, sum, cur);
}
path.pop_back();
cur -= root->val;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
TreeNode* root = new TreeNode(10);
TreeNode* rootLeft = new TreeNode(5);
TreeNode* rootRight = new TreeNode(12);
TreeNode* leftLeft = new TreeNode(4);
TreeNode* leftRight = new TreeNode(7);
root->left = rootLeft;
root->right = rootRight;
rootLeft->left = leftLeft;
rootLeft->right = leftRight;
Solution s;
s.FindPath(NULL, 22);
return 0;
}
第二次做:
这道题的本质是二叉树的前序遍历,path用来保存路径,cur以引用形式保存当前累加的路径值。计算工作交由recursive函数完成。
先写主函数:
class Solution {
public:
vector<vector<int> > FindPath(TreeNode* root,int sum) {
vector<vector<int>> retVec ;
if ( root == NULL ) return retVec ;
vector<int> path ;
int cur = 0 ;
recursive( root, retVec, path, cur, sum ) ;
return retVec ;
}
};
再写递归函数,递归函数的本质是前序遍历,所以我们先把前序遍历的架子搭起来:
void recursive( TreeNode* root, vector<vector<int>>& retVec, vector<int>& path, int& cur, int sum ) {
if ( root == NULL ) return ;// 递归退出条件
// 这里写处理代码
recursive( root->left, retVec, path, cur, sum ) ; // 左递归
recursive( root->right, retVec, path, cur, sum ) ; // 右递归
}
再加上处理代码:
void recursive( TreeNode* root, vector<vector<int>>& retVec, vector<int>& path, int& cur, int sum ) {
if ( root == NULL ) return ;
cur += root->val ; // 处理代码
path.push_back( root->val ) ; // 处理代码
bool isLeaf = ( root->left == NULL ) && ( root->right == NULL ) ; // 处理代码
if ( isLeaf && sum == cur ) { // 处理代码
retVec.push_back( path ) ; // 处理代码
}
recursive( root->left, retVec, path, cur, sum ) ;
recursive( root->right, retVec, path, cur, sum ) ;
}
往往到这里就结束了,但是这道题有点特殊,当遍历到叶子节点,但是路径值不等于sum时,要弹出当前节点值。
void recursive( TreeNode* root, vector<vector<int>>& retVec, vector<int>& path, int& cur, int sum ) {
if ( root == NULL ) return ;
cur += root->val ;
path.push_back( root->val ) ;
bool isLeaf = ( root->left == NULL ) && ( root->right == NULL ) ;
if ( isLeaf && sum == cur ) {
retVec.push_back( path ) ;
//return ;
}
recursive( root->left, retVec, path, cur, sum ) ;
recursive( root->right, retVec, path, cur, sum ) ;
path.pop_back() ; // 弹出当前叶子节点的值
cur -= root->val ; // 路径值减去当前叶子节点的值
}
第三次做:
/*
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 expNum) {
vector<vector<int>> retVec ;
if ( root == NULL ) return retVec ;
vector<int> path ;
int cur = 0 ;
recursive( root, retVec, path, expNum, cur ) ;
return retVec ;
}
void recursive( TreeNode* root, vector<vector<int>>& retVec, vector<int>& path, int &expNum, int cur ) {
if ( root == NULL ) return ;
cur += root->val ;
path.push_back( root->val ) ;
bool isLeaf = ( root->left == NULL ) && ( root->right == NULL ) ;
if ( isLeaf == true && cur == expNum ) {
retVec.push_back( path ) ;
}
recursive( root->left, retVec, path, expNum, cur ) ;
recursive( root->right, retVec, path, expNum, cur ) ;
cur -= root->val ;
path.pop_back() ;
}
};