【题目来源】
由于九度OJ(http://ac.jobdu.com/)已经永久关闭,故无法在其上进行在线提交代码。
幸运的是,在AcWing上有此题目“二叉树中和为某一值的路径”,但描述有些不同。可详见:
https://www.acwing.com/problem/content/description/45/
【题目描述】
输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。
路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。
【输入描述】
每个测试案例包括 n+1 行:
第一行为 2 个整数 n,k(1<=n<=10000),n 表示结点的个数,k 表示要求的路径和,结点编号 id 从 1 到 n 。
接下来有 n 行(第 i 行表示第 i 个结点的信息,i=1~n)。这 n 行中每行为 3 个整数 vi, leftnode, rightnode,vi 表示第 i 个结点的值,leftnode 表示第 i 个结点的左孩子结点编号,rightnode 表示第 i 个结点的右孩子结点编号,若无结点值为 -1。编号为 1 的结点为根结点。
【输出描述】
对应每个测试案例,先输出“result:”占一行,接下来按字典顺序输出满足条件的所有路径,这些路径由结点编号组成,输出格式参照输出样例。
【测试样例】
输入样例:
5 22
10 2 3
5 4 5
12 -1 -1
4 -1 -1
7 -1 -1
1 5
1 -1 -1
输出样例:
result:
A path is found: 1 2 5
A path is found: 1 3
result:
【算法分析】
** vector的 pop_back() 函数的作用是弹出 vector 中的最后一个元素。
若要深入理解本例中的 pop_back() 函数的作用,可将样例绘制为示意图后,按示意图模拟执行代码,便可直观顿悟。本题样例的图示如下:
** 由于输出需要按字典顺序输出满足条件的所有路径,所以在代码中需要对左右结点编号进行交换排序。代码如下:
if(p[i].lchild>p[i].rchild) {
int t=p[i].lchild;
p[i].lchild=p[i].rchild;
p[i].rchild=t;
}
** AcWing 上关于此题是用类实现的,参考代码如下:
/**
* 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> ans;
vector path;
vector> findPath(TreeNode* root,int sum){
dfs(root,0,sum);
return ans;
}
void dfs(TreeNode *root,int sum,int target){
if(!root) return;
path.push_back(root->val);
sum+=root->val;
if(!root->left && !root->right){
if(sum==target) ans.push_back(path);
} else{
if(root->left) dfs(root->left,sum,target);
if(root->right) dfs(root->right,sum,target);
}
path.pop_back();
}
};
【算法代码】
#include
using namespace std;
const int maxn=1e3+5;
struct Node {
int value,lchild,rchild;
} p[maxn];
vector ans;
void dfs(int cur,int sum,int id) {
if(id==-1) return;
if(sum==cur+p[id].value && p[id].lchild==-1 && p[id].rchild==-1) {
ans.push_back(id);
printf("A path is found:");
for(int i=0; icur+p[id].value) {
ans.push_back(id);
dfs(cur+p[id].value,sum,p[id].lchild);
dfs(cur+p[id].value,sum,p[id].rchild);
ans.pop_back();
}
}
int main() {
int n,tot;
while(scanf("%d %d",&n,&tot)!=EOF) {
ans.clear();
for(int i=1; i<=n; i++) {
scanf("%d %d %d",&p[i].value,&p[i].lchild,&p[i].rchild);
if(p[i].lchild>p[i].rchild) {
int t=p[i].lchild;
p[i].lchild=p[i].rchild;
p[i].rchild=t;
}
}
printf("result:\n");
dfs(0,tot,1);
}
return 0;
}
/*
in:
5 22
10 2 3
5 4 5
12 -1 -1
4 -1 -1
7 -1 -1
1 5
1 -1 -1
out:
result:
A path is found: 1 2 5
A path is found: 1 3
result:
*/
【参考文献】
https://www.cnblogs.com/llguanli/p/6951966.html
https://blog.csdn.net/qq_32867925/article/details/104851126