写在前面
- 思路分析1
- 后序遍历的顺序是先左右再树根
- 左子树不为空,答案一定在左子树
- 否则右子树不为空,答案一定在右子树
- 否则答案为根结点。
- 思路分析2
- 递归生成后序结果
- 思路分析3
- 构建树
- 后序遍历
- 知识盲点,仅懂部分待深入学习
测试用例
input:
7
1 2 3 4 5 6 7
2 3 1 5 4 7 6
output:
3
ac代码
- 参考代码1,不太懂
- 前序中序转后序,只需要知道后序第1个值
- 定义1个变量flag,当post的第1个值输出,则flag为true
- 递归出口处判断flag,提前return
#include <iostream>
#include <vector>
using namespace std;
vector<int> pre, in;
bool flag = false;
void postOrder(int prel, int inl, int inr)
{
if(inl > inr || flag == true) return;
int i=inl;
while( in[i] != pre[prel]) i++;
postOrder(prel+1, inl, i-1);
postOrder(prel+i-inl+1, i+1, inr);
if(flag == false)
{
printf("%d", in[i]);
flag = true;
}
}
int main()
{
int n;
scanf("%d", &n);
pre.resize(n);
in.resize(n);
for(int i=0; i<n; i++) scanf("%d", &pre[i]);
for(int i=0; i<n; i++) scanf("%d", &in[i]);
postOrder(0, 0, n-1);
return 0;
}
- 参考代码2
- 知识点
- 前序中序
- 算法是使用辅助递归函数,辅助函数需要记录前序数组的起点和中点,数组均使用前闭后闭约定。
- 中序左子数的区间为[inStart,inRoot-1],中序右子数的区间为[inRoot+1,inEnd]
- 前序左子数的区间为[preStart+1,preStart+(inRoot-1-inStart)+1] // 由前序左子数的个数等于中序左子树计算得到
- 前序右子数的区间为[preStart+(inRoot-inStart)+1,preEnd]
- 中序后序
- 中序左子数的区间为[inStart,inRoot-1],中序右子数的区间为[inRoot+1,inEnd]
- 后序左子数的区间为[posStart,posStart+inRoot-1-inStart],
- 后序右子数的区间为[posStart+inRoot-inStart,posEnd-1]
#include<iostream>
#include<vector>
using namespace std;
vector<int> pre, in,post;
void findRoot(int pl, int pr, int il, int ir) {
if (pl > pr)
return;
int index = il;
while (index<ir&&in[index] != pre[pl])
index++;
//left
findRoot(pl + 1, index-1-il+pl+1, il, index - 1);
//right
findRoot(pr-(ir-index-1), pr, index + 1, ir);
post.push_back(pre[pl]);
}
int main() {
//read
int n;
cin >> n;
pre.resize(n), in.resize(n);
for (int i = 0; i < n; ++i)
cin >> pre[i];
for (int i = 0; i < n; ++i)
cin >> in[i];
findRoot(0, n-1, 0, n-1);
cout << post[0] << endl;
system("pause");
return 0;
}
- 参考代码3
#include<iostream>
#include<vector>
using namespace std;
vector<int> pre, in,post;
struct node {
int val;
struct node *left, *right;
};
node* buildTree(int pl, int pr, int il, int ir) {
if (pl > pr)
return NULL;
node *root = new node;
root->val = pre[pl];
root->left = root->right = NULL;
int index = il;
while (il <= ir && in[index] != pre[pl])
index++;
root->left = buildTree(pl+1, index-1-il+pl+1, il, index - 1);
root->right = buildTree(pr-(ir-index-1), pr, index + 1, ir);
return root;
}
void dfs(node *root) {
if (root == NULL)
return;
dfs(root->left);
dfs(root->right);
post.push_back(root->val);
}
int main() {
//read
int n;
cin >> n;
pre.resize(n), in.resize(n);
for (int i = 0; i < n; ++i)
cin >> pre[i];
for (int i = 0; i < n; ++i)
cin >> in[i];
node* root = NULL;
root=buildTree(0, n - 1, 0, n - 1);
dfs(root);
cout << post[0] << endl;
system("pause");
return 0;
}