题目:
当前存在各节点最多含有2个子节点的树。树中有N个节点,每个节点在1到 N为止的自然数中获得唯一值。现在需要按照如下两种方法,通过一行输出节点的号码。
方法 1: 优先输出root的号码。然后在root的左边和右边中选择一个子树,输出这个子树的号码。然后输出相对的另一个子树的号码。输出子树里面号码的方法跟root的方法相同,需要不断反复。注意的是,每个节点上先选左边的子树还是先选右边的子树是可以随意的。
方法 2: 在root的左边和右边中选择一个子树,输出这个子树的号码。然后输出root的号码。再输出相对的另一个子树的号码。输出子树里面号码的方法跟root的方法相同,需要不断反复。注意的是,每个节点上先选左边的子树还是先选右边的子树是可以随意的。
在如下图片的树中,按照方法 1可以输出“4, 1, 5, 6, 2, 8, 3, 7”, “4, 8, 7, 3, 1, 5, 6, 2” 等。还有,按照方法2可以输出“6, 5, 2, 1, 4, 7, 8, 3”, “1, 6, 5, 2, 4, 3, 8, 7” 等。
请接收通过方法1和方法2输出的内容,编写这两个输出是否能在相同的树中做成的判断程序。
[输入]
Input文件的第一行给出文件上包含的测试用例个数。各测试用例的第一行给出树的节点个数N(1 ≤ N ≤ 100,000)。 然后下一行给出通过方法1输出的N个数。再下一行给出通过方法2输出的N个数。
[输出]
各测试用例的答案按照顺序标准输出,每个测试用例的开始输出“#x”。这时,x是测试用例号码。在同一行上隔一个空格后,当两个输出可以在相同的树中做成时,去掉引号输出“POSSIBLE”, 绝对不能在相同的树中做成时,去掉引号输出 “IMPOSSIBLE”。
[输入输出 案例]
(输入)
2
8
4 1 5 6 2 8 3 7
6 5 2 1 4 7 8 3
4
1 2 3 4
3 1 4 2
(输出)
#1 POSSIBLE
#2 IMPOSSIBLE
题目给出 两个 二叉树的遍历序列,姑且称之为 先根遍历 序列 中根遍历序列
针对这个题目:
要判断两个遍历序列是否可能 属于同一棵树
思路是:将两个序列,向下找出所有子树,一一比对
package Professional;
import java.io.BufferedReader;
//import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.util.Stack;
public class CallNumbers {
static int T, N;
static boolean answer;
static int[] arrMid = new int[100001];
static int[] arrPre = new int[100001];
static int[] arrPPos = new int[100001];
static boolean found;
public static void main(String args[]) throws Exception {
// long start = System.currentTimeMillis();
StringTokenizer st;
// System.setIn(new FileInputStream(
// "D:/AndroidProject/workspace/javatest-20150828/CallNumbers.txt"));
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
T = Integer.parseInt(br.readLine());
for (int test_case = 1; test_case <= T; test_case++) {
N = Integer.parseInt(br.readLine());
st = new StringTokenizer(br.readLine());
for (int i = 1; i <= N; i++) {
arrMid[i] = Integer.parseInt(st.nextToken());
}
st = new StringTokenizer(br.readLine());
for (int i = 1; i <= N; i++) {
arrPre[i] = Integer.parseInt(st.nextToken());
arrPPos[arrPre[i]] = i;
}
answer = true;
check(1, N, 1, N);
if (answer)
System.out.println("#" + test_case + " " + "POSSIBLE");
else
System.out.println("#" + test_case + " " + "IMPOSSIBLE");
Arrays.fill(arrMid, 0);
Arrays.fill(arrPre, 0);
Arrays.fill(arrPPos, 0);
}
// System.out.println("Time:" + (System.currentTimeMillis() - start));
}
public static void check(int ms, int me, int ps, int pe) {
Stack<Integer> stack = new Stack<Integer>();
int mroot, proot, pson;
int pls, ple, prs, pre;
int mls, mle, mrs, mre;
stack.add(ms);
stack.add(me);
stack.add(ps);
stack.add(pe);
while (!stack.isEmpty()) {
pre = stack.pop();
pls = stack.pop();
mre = stack.pop();
mroot = stack.pop();
if (mre == mroot) {
if (!(arrMid[mroot] == arrPre[pls])) {
answer = false;
return;
}
} else {
proot = arrPPos[arrMid[mroot]];
ple = proot - 1;
prs = proot + 1;
mls = mroot + 1;
if (proot == pls) {
stack.add(mls);
stack.add(mre);
stack.add(prs);
stack.add(pre);
} else if (proot == pre) {
stack.add(mls);
stack.add(mre);
stack.add(pls);
stack.add(ple);
} else if (proot > pls && proot < pre) {
pson = arrPPos[arrMid[mls]];
if (pson >= pls && pson <= ple) {
mle = mls + (ple - pls);
mrs = mle + 1;
stack.add(mls);
stack.add(mle);
stack.add(pls);
stack.add(ple);
stack.add(mrs);
stack.add(mre);
stack.add(prs);
stack.add(pre);
} else if (pson >= prs && pson <= pre) {
mle = mls + (pre - prs);
mrs = mle + 1;
stack.add(mls);
stack.add(mle);
stack.add(prs);
stack.add(pre);
stack.add(mrs);
stack.add(mre);
stack.add(pls);
stack.add(ple);
} else {
answer = false;
return;
}
} else {
answer = false;
return;
}
}
}
}
}