题目描述
输入一颗二叉树的根节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)
解题思路
- 设计一个函数,用vector存储根结点到各个叶子结点的路径,对每个路径进行判断,等于expectNumber,存入到二维vector中。
- 设计一个函数,对每个一维数组中的元素和是否等于expectNumber进行判断。
- 设计一个可以按照一维数组元素个数大小对二维数组中的一维数组进行排序的方法。
代码实现
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
bool IsEqualToExpectNumber(vector<int> &vnode, const int expectNumber) // 对每个一维数组中的元素和是否等于expectNumber进行判断
{
if(vnode.empty())
return false;
if(expectNumber <= 0)
return false;
return (expectNumber == accumulate(vnode.begin(), vnode.end(), 0));
}
void FindPathNode(TreeNode* &root, vector<vector<int> > &vnode, vector<int> &vtemp, const int expectNumber) // 打印根结点到叶子结点的路径,把符合题意的一维数组存到二维数组中
{
if (root)
{
vtemp.push_back(root->val);
if (!root->left && !root->right)
{
if (IsEqualToExpectNumber(vtemp, expectNumber))
{
vnode.push_back(vtemp);
}
}
if (root->left)
{
FindPathNode(root->left, vnode, vtemp, expectNumber);
}
if (root->right)
{
FindPathNode(root->right, vnode, vtemp, expectNumber);
}
}
if (vtemp.size())
{
vtemp.pop_back();
}
}
void SortVector(vector<vector<int> > &vnode) //按照每个一维数组元素个数对二维数组中的一维数组进行排序
{
if(vnode.empty())
return;
for(int i = 0; i < vnode.size(); i++)
{
for(int j = i + 1; j < vnode.size(); j++)
{
if(vnode[i].size() < vnode[j].size())
{
swap(vnode[i], vnode[j]); // swap可以直接用于两个vector的交换 但array类型的数组不可以
}
}
}
}
vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
if(root == NULL)
return {};
vector<vector<int> > vnode;
vector<int> vtemp;
FindPathNode(root, vnode, vtemp, expectNumber);
SortVector(vnode);
return vnode;
}
};
下面的代码是网上的:
class Solution {
public:
vector<vector<int> > buffer;
vector<int> tmp;
vector<vector<int> > FindPath(TreeNode* root,int expectNumber) {
if(root==NULL)
return buffer;
tmp.push_back(root->val);
if((expectNumber-root->val)==0 && root->left==NULL && root->right==NULL)
{
buffer.push_back(tmp);
}
FindPath(root->left,expectNumber-root->val);
FindPath(root->right,expectNumber-root->val);
if(tmp.size()!=0)
tmp.pop_back();
return buffer;
}
};
在VS2013上的运行
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include<vector>
#include<numeric>
using namespace std;
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) : // 构造函数
val(x), left(NULL), right(NULL) {
}
};
void Print2ndVector(vector<vector<int> > &vnode) // 打印二维数组
{
if (vnode.empty())
{
return;
}
vector<vector<int> >::iterator iter1 = vnode.begin();
for (; iter1 != vnode.end(); iter1++)
{
for (vector<int>::iterator iter2 = iter1->begin(); iter2 != iter1->end(); iter2++)
{
cout << *iter2 << " ";
}
cout << endl;
}
}
TreeNode* CreateTree() // 创建二叉树结点
{
TreeNode* root = new TreeNode(5); //因为struct中的构造函数 初始化必须赋值
TreeNode* left1 = new TreeNode(3);
TreeNode* right1 = new TreeNode(7);
root->right = left1; // 赋值问题 老是出错
root->left = right1;
TreeNode* left2 = new TreeNode(2);
TreeNode* right2 = new TreeNode(4);
left1->left = left2;
left1->right = right2;
return root;
}
bool IsEqualToExpectNumber(vector<int> vnode,const int expectNumber) // 判断路径和是否等于expectNumber
{
if (vnode.empty())
return false;
if (expectNumber <= 0)
return false;
return (expectNumber == accumulate(vnode.begin(), vnode.end(), 0));//accumulate 是 #include<numeric>里面的
}
void FindPathNode(TreeNode* &root, vector<vector<int> > &vnode, vector<int> &vtemp, const int expectNumber) // 打印根结点到叶子结点的路径
{ // 打印总长度为12的路径
if (root)
{
vtemp.push_back(root->val);
if (!root->left && !root->right)
{
if (IsEqualToExpectNumber(vtemp, expectNumber))
{
vnode.push_back(vtemp);
}
}
if (root->left)
{
FindPathNode(root->left, vnode, vtemp, expectNumber);
}
if (root->right)
{
FindPathNode(root->right, vnode, vtemp, expectNumber);
}
}
if (vtemp.size())
{
vtemp.pop_back();
}
}
void SortVector(vector<vector<int> > &vnode) // 将按照结点数多少对二维数组中的每个一位数组进行排序
{
if (vnode.empty())
return;
for (int i = 0; i < vnode.size(); i++)
{
for (int j = i + 1; j < vnode.size(); j++)
{
if (vnode[i].size() < vnode[j].size())
{
swap(vnode[i], vnode[j]); // swap可以直接用于两个vector的交换 但array类型的数组不可以
}
}
}
}
void main()
{
TreeNode* root = CreateTree(); // 创建二叉树结点
vector<vector<int>> vnode; // 建立二维数组
vector<int> vtemp; // 建立一维数组
int expectNumber = 12; // 定义可以匹配的路径和
FindPathNode(root, vnode, vtemp, expectNumber); // 打印总长度为12的路径
Print2ndVector(vnode); // 打印二维数组
cout << "排序之后的二维数组:" << endl;
SortVector(vnode); // 调整 将按照结点数多少对二维数组中的每个一位数组进行排序
Print2ndVector(vnode);// 打印二维数组
system("pause");
return;
}
/*
5 7
5 3 4
排序之后的二维数组:
5 3 4
5 7
请按任意键继续. . .
*/
该题目设计的知识点
1、打印二叉树根结点到所有叶子结点的路径
void AllPathFromRootToLeaves(TreeNode* &pRoot, vector<int> &vNode)
{
if(pRoot)
{
vNode.push_back(pRoot->val);
if(!pRoot->left && !pRoot->right)
printVnode(vNode); // 打印vector中的元素
if(pRoot->left)
AllPathFromRootToLeaves(pRoot->left, vNode);
if(pRoot->right)
AllPathFromRootToLeaves(pRoot->right, vNode);
}
if(vNode.size())
vNode.pop_back();
}
2、vector复制数据的方法
1、初始化时构造拷贝函数
vector<int> v1;
v1.push_back(1);
v1.push_back(2);
vector<int> v2(v1);
这种情况就是从将v1的元素复制到v2,v1不发生变化。
2、assign的用法
vector<int> v3;
v3.assign(v1.begin(), v1.end());
也是从将v1的元素复制到v3,v1不发生变化。
3、swap的用法(重点掌握)
vector<int> v4;
v4.swap(v1);
这种情况的结果是将v1中的数据全部转移到v4中,v1为空。
4、insert的用法
vector<int> v5;
v5.insert(v5.end(), v1.begin(), v2.end());
将v1中的数据全部复制插入到v5末端。
3、swap的用法简说
swap可以直接用于两个vector的交换 但array类型的数组不可以
swap(vnode[i], vnode[j]);
一个VS2013上的例子:
void Print1Vector(vector<int> &vec)
{
if (vec.empty())
{
return;
}
for (vector<int>::iterator iter = vec.begin(); iter != vec.end(); iter++)
{
cout << *iter << " ";
}
cout << endl;
}
void main()
{
vector<int> a;
a.push_back(1);
a.push_back(2);
a.push_back(3);
vector<int> b;
b.push_back(4);
b.push_back(5);
Print1Vector(a);
Print1Vector(b);
swap(a, b);
cout << "交换后: " << endl;
Print1Vector(a);
Print1Vector(b);
system("pause");
}
/*
1 2 3
4 5
交换后:
4 5
1 2 3
请按任意键继续. . .
*/