输入样例:
8
12 11 20 17 1 15 8 5
12 20 17 11 15 8 5 1
输出样例:
1 11 5 8 17 12 20 15
算法思路:
因为结点权值均不同,可以用map存储各结点的左右儿子,构造出二叉树。再通过层序遍历,将奇数层的序列翻转,偶数层的不变,最后输出结果。
控制遍历到哪一层时,可以通过两个while循环:当内层while循环完时,表明一层结束,再统一将这一层的左右儿子入队,从而控制层数。也可以先深搜出各层的结点数,while循环内通过for控制队列的出队元素数。
Java代码:(两层while控制层数)
import java.io.*;
import java.util.*;
public class Main {
static StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
public static int ini() throws IOException {
st.nextToken();
return (int)st.nval;
}
static int N = 35, n;
static int []in = new int[N];
static int []post = new int[N];
static HashMap<Integer,Integer> map = new HashMap<>();
static HashMap<Integer,Integer> l = new HashMap<>();
static HashMap<Integer,Integer> r = new HashMap<>();
public static void main(String[] args) throws IOException {
n = ini();
for(int i = 0; i < n; i++) {
in[i] = ini();
map.put(in[i], i);
}
for(int i = 0; i < n; i++) post[i] = ini();
int root = dfs(0, n - 1, 0, n - 1);
bfs(root);
}
public static int dfs(int il, int ir, int pl, int pr) {
int root = post[pr];
int k = map.get(root);
if(il < k) l.put(root, dfs(il, k - 1, pl, pl + k - 1 - il));
if(k < ir) r.put(root, dfs(k + 1, ir, pl + k - il, pr - 1));
return root;
}
public static void bfs(int root) {
Queue<Integer> qu = new LinkedList<>();
qu.add(root);
ArrayList<Integer> list = new ArrayList<>();
ArrayList<Integer> ans = new ArrayList<>();
ans.add(root);
int step = 0;
while(!qu.isEmpty()) {
while(!qu.isEmpty()) {
int t = qu.poll();
if(l.get(t) != null) list.add(l.get(t));
if(r.get(t) != null) list.add(r.get(t));
}
qu.addAll(list);
if(++step % 2 == 0) Collections.reverse(list);
ans.addAll(list);
list.clear();
}
System.out.print(ans.get(0));
for(int i = 1; i < n; i++) System.out.print(" " + ans.get(i));
}
}
Java代码:(dfs+bfs控制层数)
import java.io.*;
import java.util.*;
public class Main {
static StreamTokenizer st = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
public static int ini() throws IOException {
st.nextToken();
return (int)st.nval;
}
static int N = 35, n, maxdeep;
static int []in = new int[N];
static int []post = new int[N];
static int []deep = new int[N];
static HashMap<Integer,Integer> map = new HashMap<>();
static HashMap<Integer,Integer> l = new HashMap<>();
static HashMap<Integer,Integer> r = new HashMap<>();
public static void main(String[] args) throws IOException {
n = ini();
for(int i = 0; i < n; i++) {
in[i] = ini();
map.put(in[i], i);
}
for(int i = 0; i < n; i++) post[i] = ini();
int root = dfs(0, n - 1, 0, n - 1);
deep(root, 1);
// System.out.println("\n" + maxdeep); // 输出深度
// for(int i = 1; i <= maxdeep; i++) System.out.print(deep[i] + " "); // 输出各层结点数
bfs(root);
}
public static int dfs(int il, int ir, int pl, int pr) {
int root = post[pr];
int k = map.get(root);
if(il < k) l.put(root, dfs(il, k - 1, pl, pl + k - 1 - il));
if(k < ir) r.put(root, dfs(k + 1, ir, pl + k - il, pr - 1));
return root;
}
public static void deep(int u, int dp) { //求树的每层结点个数
maxdeep = Math.max(maxdeep, dp);
deep[dp]++;
if(l.get(u) != null) deep(l.get(u), dp + 1);
if(r.get(u) != null) deep(r.get(u), dp + 1);
}
public static void bfs(int root) {
Queue<Integer> qu = new LinkedList<>();
qu.add(root);
int idx = 1;
ArrayList<Integer> list = new ArrayList<>();
ArrayList<Integer> ans = new ArrayList<>();
while(!qu.isEmpty()) {
int cnt = deep[idx];
for(int i = 1; i <= cnt; i++) {
int t = qu.poll();
list.add(t);
if(l.get(t) != null) qu.add(l.get(t));
if(r.get(t) != null) qu.add(r.get(t));
}
if(idx++ % 2 == 1) Collections.reverse(list);
ans.addAll(list);
list.clear();
}
System.out.print(ans.get(0));
for(int i = 1; i < n; i++) System.out.print(" " + ans.get(i));
}
}