당신은 이진트리를 수로 표현하는 것을 좋아합니다.
이진트리를 수로 표현하는 방법은 다음과 같습니다.
이진트리에서 리프 노드가 아닌 노드는 자신의 왼쪽 자식이 루트인 서브트리의 노드들보다 오른쪽에 있으며, 자신의 오른쪽 자식이 루트인 서브트리의 노드들보다 왼쪽에 있다고 가정합니다.
다음은 이진트리를 수로 표현하는 예시입니다.
주어진 이진트리는 다음과 같습니다.
주어진 이진트리에 더미노드를 추가하여 포화 이진트리로 만들면 다음과 같습니다. 더미 노드는 점선으로 표시하였고, 노드 안의 수는 살펴보는 순서를 의미합니다.
노드들을 왼쪽에 있는 순서대로 살펴보며 0과 1을 생성한 문자열에 추가하면 "0111010"
이 됩니다. 이 이진수를 십진수로 변환하면 58입니다.
당신은 수가 주어졌을때, 하나의 이진트리로 해당 수를 표현할 수 있는지 알고 싶습니다.
이진트리로 만들고 싶은 수를 담은 1차원 정수 배열 numbers
가 주어집니다. numbers
에 주어진 순서대로 하나의 이진트리로 해당 수를 표현할 수 있다면 1을, 표현할 수 없다면 0을 1차원 정수 배열에 담아 return 하도록 solution 함수를 완성해주세요.
numbers
의 길이 ≤ 10,000numbers
의 원소 ≤ 1015numbers | result |
---|---|
[7, 42, 5] | [1, 1, 0] |
[63, 111, 95] | [1, 1, 0] |
입출력 예 #1
7은 다음과 같은 이진트리로 표현할 수 있습니다.
42는 다음과 같은 이진트리로 표현할 수 있습니다.
5는 이진트리로 표현할 수 없습니다.
따라서, [1, 0]을 return 하면 됩니다.
입출력 예 #2
63은 다음과 같은 이진트리로 표현할 수 있습니다.
111은 다음과 같은 이진트리로 표현할 수 있습니다.
95는 이진트리로 표현할 수 없습니다.
따라서, [1, 1, 0]을 return 하면 됩니다.
해답이 마땅히 생각나지 않아 _jake님의 velog를 참고하여 풀이 과정을 주석으로 해석하였음
function solution(numbers) {
// 2진수로 변환한 후 reverse
numbers = numbers.map((number) => number.toString(2).split('').reverse());
const isPossible = (number) => {
while (true) {
// ["1"] 이라면 이진트리로 표현이 가능하다
if (number.length === 1 && number[0] === '1') return true;
const newNumber = [];
// i는 자식 왼쪽 노드, i+1은 부모 노드, i+2는 자식 오른쪽 노드, i+3은 다음 부모 노드
for (let i = 0; i < number.length; i += 4) {
// 부모 노드가 '0' 아니면 undefined 인 가상노드일 경우 자식노드 조회
if (number[i + 1] === '0' || !number[i + 1]) {
// 왼쪽 자식 노드와 오른쪽 자식 노드 중 하나라도 값이 '1'인데 부모 노드가 가상노드인 경우, 해당 수는 이진트리로 표현불가
if (number[i] === '1' || number[i + 2] === '1') return false;
}
// 부모 노드가 있다면 '1', 없다면 '0'을 새 배열에 추가
newNumber.push(number[i + 1] || '0');
// 부모의 부모 노드가 있다면, 입력
if (number[i + 3]) newNumber.push(number[i + 3]);
}
number = newNumber;
}
};
// 0을 부모로 갖는 1 노드가 있는가를 전체 탐색하여 문제 유무 확인
const result = numbers.map((number) => (isPossible(number) ? 1 : 0));
return result;
}