2017去哪兒網線上筆試(二)_演算法題
來源:互聯網
上載者:User
//題目描述:
//給定一棵二叉樹的前序(根、左、右)和中序(左、根、右)的列印結果,輸出此二叉樹按層(從左往右)列印結果。
//例如一棵二叉樹前序:1 2 4 5 3;中序:4 2 5 1 3。可以構建出下圖所示二叉樹:
//
//
//按層列印的結果則為:1 2 3 4 5。
//
//輸入
//第一行只有一個數字,表示二叉樹的節點數n(1<=n<=1000);
//第二行由a1,a2,...,an(1<=ai<=1000)組成的整數序列(用空格分隔)—表示前序列印結果;
//第三行由b1,b2,...,bn(1<=bi<=1000)組成的整數序列(用空格分隔)—表示中序列印結果。
//
//輸出
//c1,c2,...,cn,用空格分隔—表示按層列印的結果。
//
//
//範例輸入
//5
//1 2 4 5 3
//4 2 5 1 3
//
//範例輸出
//1 2 3 4 5
class Worker{
/*數組的長度*/
int ILength;
/*結果數組已有的字數數量*/
int ITreeNum = 0;
/*結果數組裡新樹的最左下標*/
int INewTreeLeft = -1;
/*結果數組裡新樹的最右下標*/
int INewTreeRight = 0;
char tempC[];
/*結果數組*/
int result[][];
/*前序數組*/
String qian[];
/*中序數組*/
String zhong[][];
StringBuilder builder;
public Worker(){
builder = new StringBuilder("");
}
/*根據輸入的第一行為ILength賦值*/
public void setLength(String s){
int lenght = 0;
tempC = s.toCharArray();
for(int i = tempC.length - 1,j = 0; i >= 0; i--,j++){
lenght += (tempC[i] - '0') * chengfang(j);
}
ILength = lenght;
}
/*根據第二行第三行輸入的字串初始化前序中序的數組,並建立結果序列數組*/
public void init(String s0, String s1){
int i = 0,j = 0;
qian = new String[ILength];
zhong = new String[ILength][2];
result = new int[ILength][3];
tempC = s0.toCharArray();
int length = s0.length();
for(i = 0, j = 0; i < length; i++){
if(tempC[i] != ' '){
builder.append(tempC[i]);
if(i == length -1){
qian[j] = builder.toString();
builder.delete(0, builder.capacity());
}
}else{
if(!builder.toString().trim().equals(null)){
qian[j] = builder.toString();
builder.delete(0, builder.capacity());
j++;
}
}
}
tempC = s1.toCharArray();
for(i = 0, j = 0; i < length; i++){
if(tempC[i] != ' '){
builder.append(tempC[i]);
if(i == length -1){
zhong[j][0] = builder.toString();
builder.delete(0, builder.capacity());
}
}else{
if(!builder.toString().trim().equals(null)){
zhong[j][0] = builder.toString();
builder.delete(0, builder.capacity());
j++;
}
}
}
for(i = 0; i < ILength; i++){
zhong[i][1] = "0";
result[i][0] = 0;
result[i][1] = 0;
result[i][2] = 0;
}
}
/*輸入前序數組目標的下標值,輸出目標在中序數組裡的下標值*/
public int findZhongAdd(int index){
if(index >= ILength){
return -1;
}
String s = qian[index];
for(int i = 0; i < ILength; i++){
if(s.equals(zhong[i][0])){
return i;
}
}
return -1;
}
/*輸入中序數組裡目標的下標值,計算該目標左子樹的個數*/
public int countLeftNum(int index){
int num = 0;
while((index - 1) >= 0 && (zhong[index - 1][1].equals("0"))){
index--;
num++;
}
return num;
}
/*輸入右子樹下標值,判斷是否有效*/
public boolean checkRight(int rightAddr){
if((rightAddr >= 0) && (rightAddr < ILength) && zhong[rightAddr][1].equals("0"))
return true;
return false;
}
/*計算10的i次方*/
public int chengfang(int i){
int result = 1;
if(i == 0)
return result;
for(int ii = 0; ii < i; ii++){
result *= 10;
}
return result;
}
/*
* 輸入結果數組的下標,處理左子樹及右子樹
*/
public void xxx(int i){
int root = 0;
int left = 0;
int right = 0;
int temp = 0;
int num = 0;
if(result[i][1] != -1){
root = result[i][1];
temp = findZhongAdd(result[i][1]);
num = countLeftNum(temp);
if(num > 0){
left = root + 1;
right = left + num;
}else{
left = -1;
right = root + 1;
}
if(!checkRight(findZhongAdd(right))){
right = -1;
}
result[ITreeNum][0] = root;
result[ITreeNum][1] = left;
result[ITreeNum][2] = right;
ITreeNum++;
zhong[temp][1] = "1";
if(left != -1){
zhong[findZhongAdd(left)][1] = "1";
}
if(right != -1){
zhong[findZhongAdd(right)][1] = "1";
}
}
if(result[i][2] != -1){
root = result[i][2];
temp = findZhongAdd(result[i][2]);
num = countLeftNum(temp);
if(num > 0){
left = root + 1;
right = left + num;
}else{
left = -1;
right = root + 1;
}
if(!checkRight(findZhongAdd(right))){
right = -1;
}
result[ITreeNum][0] = root;
result[ITreeNum][1] = left;
result[ITreeNum][2] = right;
ITreeNum++;
zhong[temp][1] = "1";
if(left != -1){
zhong[findZhongAdd(left)][1] = "1";
}
if(right != -1){
zhong[findZhongAdd(right)][1] = "1";
}
}
}
/*輸出結果數組*/
public void doit(){
int temp = 0;
int rootLoc = 0;
int leftLoc = 0;
int rightLoc = 0;
int num = 0;
while(INewTreeLeft < (ILength - 1)){
if(INewTreeLeft == -1){
rootLoc = 0;
temp = findZhongAdd(0);
num = countLeftNum(temp);
if(num > 0){
leftLoc = rootLoc + 1;
rightLoc = leftLoc + num;
}else{
leftLoc = -1;
rightLoc = rootLoc + 1;
}
if(!checkRight(findZhongAdd(rightLoc))){
rightLoc = -1;
}
result[ITreeNum][0] = rootLoc;
result[ITreeNum][1] = leftLoc;
result[ITreeNum][2] = rightLoc;
ITreeNum++;
zhong[temp][1] = "1";
if(leftLoc != -1){
zhong[findZhongAdd(leftLoc)][1] = "1";
}
if(rightLoc != -1){
zhong[findZhongAdd(rightLoc)][1] = "1";
}
}else{
xxx(INewTreeLeft);
}
INewTreeLeft++;
}
}
public void printLength(){
System.out.println(ILength);
}
public void printQianZhong(){
for(int i = 0; i < ILength; i++){
System.out.print(qian[i] + " ");
}
System.out.println();
for(int i = 0; i < ILength; i++){
System.out.print(zhong[i][0] + " ");
}
System.out.println();
for(int i = 0; i < ILength; i++){
System.out.print(zhong[i][1] + " ");
}
System.out.println();
}
public void printResult(){
for(int i = 0; i < ILength; i++){
System.out.print(result[i][0] + " ");
}
System.out.println();
for(int i = 0; i < ILength; i++){
System.out.print(result[i][1] + " ");
}
System.out.println();
for(int i = 0; i < ILength; i++){
System.out.print(result[i][2] + " ");
}
System.out.println();
}
}
public class Qunar {
public static void main(String[] args) {
// TODO 自動產生的方法存根
Worker w = new Worker();
//測試1
w.setLength("5");
w.init("1 2 4 5 3", "4 2 5 1 3");
//測試2
// w.setLength("9");
// w.init("1 2 4 5 8 9 3 6 7", "4 2 9 8 5 1 6 3 7");
w.printLength();
w.printQianZhong();
w.doit();
w.printResult();
}
}