[프로그래머스] 150367. 표현 가능한 이진트리 _ Java

jii0_0·2023년 2월 23일
0

PROGRAMMERS

목록 보기
1/3

표현 가능한 이진트리 (level 3)

문제 링크

구분

코딩테스트 연습 > 2023 KAKAO BLIND RECRUITMENT

채점결과


정확성: 100.0
합계: 100.0 / 100.0

문제 설명

당신은 이진트리를 수로 표현하는 것을 좋아합니다.

이진트리를 수로 표현하는 방법은 다음과 같습니다.

  1. 이진수를 저장할 빈 문자열을 생성합니다.
  2. 주어진 이진트리에 더미 노드를 추가하여 포화 이진트리로 만듭니다. 루트 노드는 그대로 유지합니다.
  3. 만들어진 포화 이진트리의 노드들을 가장 왼쪽 노드부터 가장 오른쪽 노드까지, 왼쪽에 있는 순서대로 살펴봅니다. 노드의 높이는 살펴보는 순서에 영향을 끼치지 않습니다.
  4. 살펴본 노드가 더미 노드라면, 문자열 뒤에 0을 추가합니다. 살펴본 노드가 더미 노드가 아니라면, 문자열 뒤에 1을 추가합니다.
  5. 문자열에 저장된 이진수를 십진수로 변환합니다.

이진트리에서 리프 노드가 아닌 노드는 자신의 왼쪽 자식이 루트인 서브트리의 노드들보다 오른쪽에 있으며, 자신의 오른쪽 자식이 루트인 서브트리의 노드들보다 왼쪽에 있다고 가정합니다.

다음은 이진트리를 수로 표현하는 예시입니다.

주어진 이진트리는 다음과 같습니다.
제목 없는 다이어그램.drawio \(4\).png

주어진 이진트리에 더미노드를 추가하여 포화 이진트리로 만들면 다음과 같습니다. 더미 노드는 점선으로 표시하였고, 노드 안의 수는 살펴보는 순서를 의미합니다.
제목 없는 다이어그램.drawio \(5\).png

노드들을 왼쪽에 있는 순서대로 살펴보며 0과 1을 생성한 문자열에 추가하면 "0111010"이 됩니다. 이 이진수를 십진수로 변환하면 58입니다.

당신은 수가 주어졌을때, 하나의 이진트리로 해당 수를 표현할 수 있는지 알고 싶습니다.

이진트리로 만들고 싶은 수를 담은 1차원 정수 배열 numbers가 주어집니다. numbers에 주어진 순서대로 하나의 이진트리로 해당 수를 표현할 수 있다면 1을, 표현할 수 없다면 0을 1차원 정수 배열에 담아 return 하도록 solution 함수를 완성해주세요.


제한사항
  • 1 ≤ numbers의 길이 ≤ 10,000
    • 1 ≤ numbers의 원소 ≤ 1015

입출력 예
numbers result
[7, 42, 5] [1, 1, 0]
[63, 111, 95] [1, 1, 0]

문제 풀이

  • 처음엔 아 쉽네 ! 했는데 포화이진트리를 생각을 못하고 그냥 String변환해서 푸는 생각만 했었다.
  • 문제1. 숫자를 이진수로 바꿔서 해당 숫자를 포화이진트리에 채워넣는 과정을 생략함
    • 높이가 H인 포화 이진트리 전체 노드 수 = 2^H - 1
    • 부모 노드가 0일 경우 리프노드까지 모든 자식 노드는 1이면 안됨
  • 문제2. Long을 이진수로 변환하는 과정
    • 처음에 분명 내 풀이가 맞는 것 같은데 16번 tc부터 다 틀려서 왜지왜지 했는데
    • Integer.toString(n, 2)로 이진수로 변환해서 그런거였음
      - Long.toBinaryString(n)으로 변환했어야 했다.

Solution


class Solution {
    static int result;
    static boolean[] binary;
	static int treeLen;
    
    public int[] solution(long[] numbers) {
        int n = numbers.length;
        int[] answer = new int[n];
        for (int i = 0; i < n; i++) {
            String b = Long.toBinaryString(numbers[i]);

            int length = b.length();
            int exp = 1;
            do {
                treeLen = (int) Math.pow(2, exp++) - 1;
            } while (treeLen < length);

            binary = new boolean[treeLen];
            int idx = treeLen - length;
            for(int j=0; j<length; j++) {
                binary[idx++] = b.charAt(j) == '1';
            }

            result = 1;
            possible(0, treeLen-1, false); // s, e, 해당 루트가 더미인지
            answer[i] = result;
        }
        return answer;

    }

    public static void possible(int s, int e, boolean check) {
        int mid = (s+e)/2;
        if(check && binary[mid]) { //루트가 0이면 자식노드들에서 1이나오면 안됨
            result = 0;
            return;
        }

        // 내가 마지막 노드가 아니면 재귀
        if(s!=e) {
            possible(s, mid-1, !binary[mid]); // 왼쪽, 현재 루트가 더미이면 check = true
            possible(mid+1, e, !binary[mid]); // 오른쪽
        }

    }
}
profile
느려도 꾸준히

0개의 댓글