题目描述:
二叉树也可以用数组来存储,
给定一个数组,树的根节点的值储存在下标1,
对于储存在下标n的节点,他的左子节点和右子节点分别储存在下标2n和2n+1,
并且我们用-1代表一个节点为空,
给定一个数组存储的二叉树,
试求从根节点到最小的叶子节点的路径,
路径由节点的值组成。
输入描述
输入一行为数组的内容,
数组的每个元素都是正整数,元素间用空格分割,
注意第一个元素即为根节点的值,
即数组的第n元素对应下标n,
下标0在树的表示中没有使用,所以我们省略了,
输入的树最多为7层。
输出描述
输出从根节点到最小叶子节点的路径上各个节点的值,
由空格分割,
用例保证最小叶子节点只有一个。
示例一
输入
3 5 7 -1 -1 2 4
输出
3 7 2
示例二
输入
5 9 8 -1 -1 7 -1 -1 -1 -1 -1 6
输出
5 8 7 6
using namespace std;
vector<int>arr;
vector<int>res;
class Solution
{
public:
public:
void Getnext(vector<int>& arr, int i, int &min,int &index) {
if (i > arr.size() - 1 || arr[i] == -1)
{
return;
}
if (i <= arr.size() - 1 && arr[i] <= min && i * 2>arr.size() - 1 && arr[i] != -1)
{
min = arr[i];
index = i;
return;
}
Getnext(arr, i * 2, min,index);
Getnext(arr, i * 2 + 1, min,index);
return;
}
/*void Get_path(vector<int>& arr, int target, int i)
{
if (i > arr.size() - 1||arr[i]==-1)
{
return;
}
if (i <= arr.size()-1&&arr[i] == target && i*2>arr.size()-1)
{
res.push_back(arr[i]);
return;
}
else if (i<=arr.size()-1&&arr[i] != target && i * 2 > arr.size()-1)
{
res.pop_back();
return;
}
res.push_back(arr[i]);
Get_path(arr, target, i * 2);
Get_path(arr, target,i * 2 + 1);
return;
}*/
void print(vector<int>& arr, int target, int index, vector<int>& res) {
//if (index % 2 != 0) {
for (int i = index; i > 0; i = i / 2)
{
res.push_back(arr[i]);
}
reverse(res.begin(), res.end());
}
};
int main()
{
Solution s1;
int num = 0,i=1;
arr.push_back(0);
while(cin>>num){
arr.push_back(num);
if (getchar() == '\n') {
break;
}
}
int min = arr[arr.size()-1];
int index=-1;
s1.Getnext(arr,i,min,index);
s1.print(arr,min,index,res);
for (int i = 0; i < res.size(); i++)
{
cout << res[i] << " ";
}
return 0;
}
最开始用回溯做不出来,后来勉强借用其他优秀的小伙伴的思路把后半段完成(后半段是已经找到最小节点之后)
先找到最小节点,获得最小节点应的下标,最后输出即可。
需要注意的点:
一是局部变量的传参,比如放最小值得min,传函数时要带引用,还是那一会事,形参不改变实参的值。
二是注意本题数组开始是1开始,而实际运算时也要从零开始考虑,(各方面都不能有疏忽)
三是min开始的初始化要初始节点的值,具体哪 个叶子节点无所谓,在函数中比较大小时要注意是小于等于,才行。
四是在最后排序时不要先sort升序排后在sort,把指针反着写在来一遍sort,有时候会访问越界,有时候虽然其他人这么写的,咱们就reverse就行了