[java]표현 가능한 이진트리 - 2023 KAKAO BLIND(4)
문제
풀이
문제 해석을 하자면,
- 먼저, 이진트리를 표현하는 방법(조건)을 제시합니다.
- 이후 숫자가 주어지면 이진트리로 표현할 수 있는지를 물어봅니다.
풀이
- 이진화
-
이진트리 판별위해 이진화 앞에 ‘0’최대 붙이기 -> “포화 이진트리로 만들기 위해”
- 이진수를 생각해보면 0001 은 십진수로 1이다
- 앞에 0을 빼도 1로 잘 표현된다
- 즉, 오른쪽부터 숫자가 채워지므로
이진수 맨앞에 0을 붙이자
-
이진트리 판별 -> 더미노드(0)을 사용하기 때문에 문제없는지 확인이 필요
- 이진트리의 루트노드가 0이면 서브트리의 루트도 0이어야 한다. -> 이 문제에서 제시한 조건이다!
- 이것은 문제 특성상 더미노드가 0이므로 더미노드 자식이 1일 수가 없기 때문이다
코드
import java.util.*;
// substring은 비효율이긴 하지만 구현이 쉬워서 index사용 대신 이것으로 진행
class Solution {
public Boolean isBinaryTree(String binary) {
// base condition
if(binary.length()==0) return true;
int root = binary.length()/2;
String left = binary.substring(0, root); // 비효율이긴 함
String right = binary.substring(root+1);
if(binary.charAt(root) == '0') { // 루트 노드가 0이라면 서브 트리도 모두 0
return isZeroTree(left) && isZeroTree(right);
}
else { // 루트 노드가 1이라면 서브 트리 검사
return isBinaryTree(left) && isBinaryTree(right);
}
}
public Boolean isZeroTree(String binary) {
// base condition
if(binary.length()==0) return true;
int root = binary.length()/2;
String left = binary.substring(0, root); // 비효율이긴 함
String right = binary.substring(root+1);
if (binary.charAt(root) == '1') { // 루트 노드가 1이라면 실패
return false;
}
else { // 루트 노드가 0이라면 서브트리 계속 확인
return isZeroTree(left) && isZeroTree(right);
}
}
public String plusZero(String binary) {
int size = binary.length();
int level = 1;
int count = 1;
while(size > count) {
count+=Math.pow(2,level);
level+=1;
}
int dif = count-size;
for(int i=0; i<dif; i++) binary = "0"+binary;
return binary;
}
public String toBinary(long num) {
String binary = "";
Stack<Long> st = new Stack<>();
long res = 0;
while(num != 0) {
res=num%2;
num/=2;
st.add(res);
}
while(!st.isEmpty()) {
binary+=st.peek(); // 비효율이긴 함
st.pop();
}
// 2. 이진화 앞에 '0'최대 붙이기
binary = plusZero(binary);
return binary;
}
public int[] solution(long[] numbers) {
int[] answer = new int[numbers.length];
for(int i=0; i<numbers.length; i++) {
// 1. 이진화 (+"포화 이진트리")
String binary = toBinary(numbers[i]);
//System.out.println(binary); // debug
// 3. 이진트리 판별
Boolean result = isBinaryTree(binary);
if(result) answer[i] = 1;
else answer[i] = 0;
}
return answer;
}
}
느낀점
풀이는 좀 비슷하게 생각했었지만 구현을 전혀 못했고, 구글링의 힘을 빌렸다.
이진트리 순회와 분할정복은 잘 아는 내용이었는데도 구현이 어려웠다.
다시 풀어보자.
댓글남기기