自上而下对左侧分支访问的同时将右子树根节点入栈,自下而上对右子树遍历。
class Solution {
public:
stack<TreeNode*> stk;
vector<int> pre;
void travelLeft(TreeNode* x){
while(x){
stk.push(x->right);
pre.push_back(x->val);
x = x->left;
}
}
vector<int> preorderTraversal(TreeNode* root) {
if(!root) return pre;
stk.push(root);
while(stk.size()){
auto t = stk.top(); stk.pop();
travelLeft(t);
}
return pre;
}
};
自上而下一路向左遍历找到该树最左侧的节点,并用栈记录下最左侧的节点的祖先,访问完最左节点后开始遍历右子树。
class Solution {
public:
vector<int> in;
stack<TreeNode*> stk;
void traverLeft(TreeNode* x){
while(x){
stk.push(x);
x = x->left;
}
}
vector<int> inorderTraversal(TreeNode* root) {
TreeNode* p = root;
while(true){
traverLeft(p);
if(stk.empty()) return in;
p = stk.top(); stk.pop();
in.push_back(p->val);
p = p->right;
}
return in;
}
};
找到第一个被访问的节点,并用栈记录下沿途经过的节点以及它们的右孩子。访问结束后,依次访问右孩子。
class Solution {
public:
stack<TreeNode*> stk;
vector<int> post;
void gotoFirst(){
while(auto p = stk.top()){
//一路向左
if(p->left){
//右孩子后入栈
if(p->right) stk.push(p->right);
stk.push(p->left);
}
//没有左孩子时转向右
else stk.push(p->right);
}
//弹出空指针
stk.pop();
}
vector<int> postorderTraversal(TreeNode* root) {
if(!root) return post;
TreeNode* p = root;
stk.push(root);
while(!stk.empty()){
//如果栈顶节点不是上一个遍历过的节点的父亲
//则栈顶节点必然是p的右兄弟
if(stk.top()->left != p && stk.top()->right != p)
gotoFirst();
p = stk.top(); stk.pop();
post.push_back(p->val);
}
return post;
}
};
class Solution {
public:
vector<int> pre, in;
unordered_map<int, int> pos;
TreeNode* dfs(int pl, int pr, int il, int ir) {
int r = pre[pl], k = pos[r];
auto root = new TreeNode(r);
if(il <= k-1) root->left = dfs(pl+1, pl+1+k-1-il, il, k-1);
if(k+1 <= ir) root->right = dfs(pl+k-il+1, pr, k+1, ir);
return root;
}
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
if(preorder.empty() || inorder.empty()) return NULL;
pre = preorder, in = inorder;
for(int i = 0; i < in.size(); i ++)
pos[in[i]] = i;
return dfs(0, pre.size()-1, 0, in.size()-1);
}
};
class Solution {
public:
unordered_map<int, int> pos;
vector<int> post;
TreeNode* dfs(int il, int ir, int pl, int pr){
int r = post[pr], k = pos[r];
auto root = new TreeNode(r);
if(k-1 >= il) root->left = dfs(il, k-1, pl, pl+k-1-il);
if(k+1 <= ir) root->right = dfs(k+1, ir, pl+k-il, pr-1);
return root;
}
TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
if(inorder.empty() || postorder.empty()) return NULL;
post = postorder;
int n = inorder.size();
for(int i = 0; i < n; i ++)
pos[inorder[i]] = i;
return dfs(0, n-1, 0, n-1);
}
};
前序序列和后序序列无法完全确定一颗二叉树,除非这是一棵真二叉树(每个节点的度数只能是2或0)。
class Solution {
public:
unordered_map<int, int> pos;
vector<int> pre, post;
TreeNode* dfs(int l1, int r1, int l2, int r2){
if(l2 > r2) return NULL;
auto root = new TreeNode(post[r2]);
if(l2 == r2) return root;
int k = pos[pre[l1+1]];
root->left = dfs(l1+1, l1+1+k-l2, l2, k);
root->right = dfs(l1+2+k-l2, r1, k+1, r2-1);
return root;
}
TreeNode* constructFromPrePost(vector<int>& _pre, vector<int>& _post) {
if(_pre.empty() || _post.empty()) return NULL;
pre = _pre, post = _post;
int n = post.size();
for(int i = 0; i < n; i ++)
pos[post[i]] = i;
return dfs(0, n-1, 0, n-1);
}
};
#include
using namespace std;
const int N = 35;
int pre[N], post[N];
int dfs(int l1, int r1, int l2, int r2, string& in){
if(l1 > r1) return 1;
if(pre[l1] != post[r2]) return 0;
int cnt = 0;
for(int i = l1; i <= r1; i ++){
string lin, rin;
int lcnt = dfs(l1+1, i, l2, l2+i-l1-1, lin);
int rcnt = dfs(i+1, r1, l2+i-l1, r2-1, rin);
if(lcnt && rcnt){
in = lin + to_string(pre[l1]) + " " + rin;
cnt += lcnt*rcnt;
}
if(cnt > 1) break;
}
return cnt;
}
int main(){
int n;
cin >> n;
for(int i = 0; i < n; i ++){
scanf("%d", &pre[i]);
}
for(int i = 0; i < n; i ++){
scanf("%d", &post[i]);
}
string in;
int cnt = dfs(0, n-1, 0, n-1, in);
in.pop_back();
if(cnt == 1) puts("Yes");
else puts("No");
cout << in << endl;
}