Don't give up!

[백준] 1068번 : 트리 (java) 본문

Coding Test/BOJ

[백준] 1068번 : 트리 (java)

Heang Lee 2021. 7. 23. 23:41

1068번: 트리 (acmicpc.net)

 

1068번: 트리

첫째 줄에 트리의 노드의 개수 N이 주어진다. N은 50보다 작거나 같은 자연수이다. 둘째 줄에는 0번 노드부터 N-1번 노드까지, 각 노드의 부모가 주어진다. 만약 부모가 없다면 (루트) -1이 주어진다

www.acmicpc.net

어떻게 생각하고 문제를 풀었는가?

주어진 입력이 i번째 노드의 부모 노드가 몇번째 노드인지 나타내고 있고, 0번째 노드가 루트 노드가 아닐 수 있다는 점, 자식 노드의 수가 정해져 있지 않다는 점을 고려하였습니다.

이를 해결하고자 N개의 노드가 가리키는 부모 노드의 인덱스를 노드 초기화시 저장하고, 모든 노드가 초기화된 후 각 노드가 가리키는 부모 노드의 자식 노드를 추가하도록 하였습니다.

노드의 삭제시 자식 노드에서 해당 노드를 삭제, 리프 노드 계산은 루트 노드에서 시작하여 자식 노드를 dfs로 탐색하도록 하여 문제를 해결할 수 있다고 생각하였습니다.

코드

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

class Main {
    static int N, target, root;
    static Node[] tree;
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        N = Integer.parseInt(reader.readLine());
        tree = new Node[N];
        StringTokenizer parentTokenizer = new StringTokenizer(reader.readLine());
        for(int i=0; i<N; i++){
            int parent = Integer.parseInt(parentTokenizer.nextToken());
            tree[i] = new Node(parent);
            if(parent<0) root = i;
        }
        target = Integer.parseInt(reader.readLine());
        reader.close();
        for(int i=0; i<N; i++){
            if(!tree[i].isRoot()){
                int parent = tree[i].parent;
                tree[parent].addChild(i);
            }
        }
        if(target == root){
            System.out.println(0);
        }else{
            int parent = tree[target].parent;
            tree[parent].removeChild(target);
            int leafSize = getLeafSize(root);
            System.out.println(leafSize);
        }
    }

    static int getLeafSize(int index){
        if(tree[index].isLeaf()) return 1;
        int sum = 0;
        for(int i=0; i<tree[index].getChildrenSize(); i++){
            sum += getLeafSize(tree[index].children.get(i));
        }
        return sum;
    }
}
class Node{
    int parent;
    List<Integer> children;

    public Node(int parent){
        this.parent = parent;
        this.children = new ArrayList<>();
    }

    public void addChild(int child){
        this.children.add(child);
    }

    public void removeChild(int child){
        this.children.remove(Integer.valueOf(child));
    }

    public boolean isLeaf(){
        return this.children.isEmpty();
    }

    public int getChildrenSize(){
        return this.children.size();
    }

    public boolean isRoot(){
        return this.parent < 0;
    }
}

Node 클래스를 선언, Node 배열 N개를 초기화하여 i번째 노드에 접근할 수 있습니다.

부모 노드의 인덱스, 자식 노드들의 인덱스를 저장한 후, 배열로부터 이를 찾아 자식노드를 추가하고 리프 노드인지 확인할 수 있습니다.

삭제하려는 노드가 루트 노드라면 모든 노드가 삭제되었으므로 0을 리턴, 루트 노드가 아니라면 해당 노드의 부모 노드로에게 자식 리스트에서 제거하도록 하고, 루트 노드로부터 dfs를 수행합니다.