[Java]BOJ 5639バイナリブラックツリー(ツリー)


BOJ 5639 S 1バイナリ検索ツリー

  • ツリー
  • silver1
  • 🔍 問題の説明


    https://www.acmicpc.net/problem/5639
    バイナリ検索ツリーは、次の3つの条件を満たすバイナリツリーです.
  • ノードの左側のサブツリー内のすべてのノードの鍵は、ノードの鍵よりも小さい.
  • ノードの右側のサブツリーでは、すべてのノードの鍵がノードの鍵よりも大きい.
  • 左、右サブツリーもバイナリ検索ツリーです.
  • 前の列の順序(ルート-左-右)でルートにアクセスし、左、右のサブツリーに順次アクセスし、ノードの鍵を出力します.後ろの順序(左-右-ルート)キーを左サブツリー、右サブツリー、ルートノードの順序で出力します.例えば、上のバイナリ検索ツリーの前列ループ結果は50302,452,845,985,260であり、後列ループ結果は5228244530,065,9850である.

    バイナリ検索ツリーの前列巡視結果が指定されている場合は、プログラムを作成してツリーを後列巡視します.

    ✔入力


    ツリーに前衛ツアーの結果をあげます.ノード内のキーの値は106未満の整数です.各値は1行1個で、ノード数は10000個以下です.同じ鍵を持つノードはありません.

    ✔出力


    入力として,与えられたバイナリ探索ツリーの後列巡回の結果を行ごとに出力する.

    💡 に答える


    前衛巡視時には、root->left->rightの順にノードにアクセスします.
    後列巡回時には、left->right->rootの順にノードにアクセスします.
    このため、ツリーの前列巡視結果を後列巡視結果に変換する手順は、次のとおりです.
  • まず、木電位巡回結果に基づいて、rootからleftrightに区分される.
    このとき、leftroot未満のノードであり、rightrootより大きいノードである.
  • int root = preTree.get(start);
    
    int right = start+1;
    for(int i = start+1 ; i <= end ; i++) {
    	if(root < preTree.get(i)) { //right를 찾는다.
    		right = i;
    		break;
    	}
    }
  • で区切られたleftrightを基に、もう一度プロセスを繰り返す.
  • getPostOrderTree(start+1, right-1); //왼쪽 서브트리 
    getPostOrderTree(right, end); //오른쪽 서브트리
  • コースを訪問します.
  • 💡 ソースコード

    package week23.BOJ_5639_S1_이진검색트리;
    
    import java.io.BufferedReader;
    import java.io.FileInputStream;
    import java.io.InputStreamReader;
    import java.util.ArrayList;
    
    /**
     * 
     * 
     * ✨ Algorithm ✨
     * 
     * @Problem : BOJ 5639 이진검색트리
     * 이진 검색 트리를 전위 순회한 결과가 주어졌을 때, 이 트리를 후위 순회한 결과를 구하는 프로그램을 작성하시오.
     * 
     * @Author : Daun JO
     * @Date : 2021. 8. 8. 
     * 
     *
     */
    public class Main_BOJ_5639_S1_이진검색트리 {
    	
    
    	static ArrayList<Integer> preTree;
    	static ArrayList<Integer> postTree;
    	static int N;
    	public static void main(String[] args) throws Exception {
    		
    		//System.setIn(new FileInputStream("5639input.txt"));
    		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    		
    		preTree = new ArrayList<>();
    
    		//트리를 전위 순회한 결과가 주어진다.
    		 while(true) {
    			 String input = br.readLine();
    			 if(input == null ) {
    				 break;
    			 }
    			 preTree.add(Integer.parseInt(input));
    		}
    
    		//전위순회 : root->left->right
    		//후위순회 : left->right->root
    		
    		//left는 root보다 작고, right는 root보다 크다
    		
    		N = preTree.size();
    		getPostOrderTree(0, N-1);
    		
    	}
    	private static void getPostOrderTree(int start, int end) {
    
    		if(start>end) return; //기저조건
    
    		int root = preTree.get(start);
    
    		int right = start+1;
    		for(int i = start+1 ; i <= end ; i++) {
    			if(root < preTree.get(i)) { //right를 찾는다.
    				right = i;
    				break;
    			}
    		}
    		
    		getPostOrderTree(start+1, right-1); //왼쪽 서브트리 
    		getPostOrderTree(right, end); //오른쪽 서브트리
    		
    		System.out.println(root); //루트 출력
    	}
    	
    }
    
    

    💯 採点結果


    メモリ25880時間800