题目
笛卡尔树 是由一系列不同数字构成的二叉树。
树满足堆的性质,中序遍历返回原始序列。
最小笛卡尔树表示满足小根堆性质的笛卡尔树。
例如,给定序列 {8,15,3,4,1,5,12,10,18,6},则生成的最小堆笛卡尔树如图所示。
6a99f68a-6578-46e0-9232-fbf0adf3691f.jpg
现在,给定一个长度为 N 的原始序列,请你生成最小堆笛卡尔树,并输出其层序遍历序列。
输入格式
第一行包含整数 N。
第二行包含 N 个两两不同的整数,表示原始序列。
输出格式
共一行,输出最小堆笛卡尔树的层序遍历序列。
数据范围
1≤N≤30,
原始序列中元素的取值范围 [−2147483648,2147483647]。
输入样例:
10
8 15 3 4 1 5 12 10 18 6
输出样例:
1 3 5 8 4 6 15 10 12 18
题目的大致意思就是指,首先找到最小的数字,然后以这个数字为一个节点,寻找左右两边最小的数字,然后将他们分别作为左右节点,然后一直持续下去,由于是左右,所以当最小的数字处于边界的时候,就不会产生两个分支,而是一个
由此我们,只需要无限递归就可以了,每次递归下去的是下一个的左边界与右边界,同时还要传递层数
题解
#include <bits/stdc++.h>
using namespace std;
int a[35];
vector<int> res[35];
// 布置多重的树杈
void dfs(int start,int end,int level)
{
if (start>=end)
{
return ;
}
int check = start;
for (int i = start; i < end; i++)
{
if (a[i]<a[check])
// 寻找一边最小的地方
// 然后又以这个地方为一个中心,像两边扩展
{
check=i;
}
}
// cout << check <<" ";
res[level].push_back(a[check]);
dfs(start,check,level+1);
// check不能要了,但是由于是<,所以这样子写
dfs(check+1,end,level+1);
}
int main()
{
int len;cin >>len;
for (int i = 0; i < len; i++)
{
cin >>a[i];
}
dfs(0,len,1);
for (auto x : res) {
for (int j = 0; j < x.size(); j++) {
cout << x[j] << ' ';
}
}
}
ac截图