728x90
https://school.programmers.co.kr/learn/courses/30/lessons/150367
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
📄 문제개요
- 특정 숫자가 주어질때 해당숫자를 이진수로 만들고, 이진수를 만든뒤, 포화 이진트리를 만든다.
- 예를들어 포화 이진트리는 아래와 같다.
- 루트노드가 1이면 자식노드는 0또는 1을 갖는다.
- 루트노드가 0이면 자식노드들도 0이 되어야한다.
🤔 문제분석
- 특정숫자를 이진수로 만든뒤 포화 이진트리로 만들어야한다.
- 높이가 n일때, 포화 이진트리는 노드의 개수가 2^n -1 를 갖는다.
- 숫자에 왼쪽에 ‘0’을 추가하면 숫자값은 바뀌지 않는다.
- 따라서 포화 이진트리는 노드의 개수를 구하고, 현재 만든 이진수와 노드의 개수를 뺀 나머지를 0으로 왼쪽에 채운다.
- 새로 만든 이진수를 아래의 2개의 조건으로 나누어 푼다.
- 루트노드가 1이면 왼쪽, 오른쪽 노드 그룹이 올바른 노드인지 확인한다.
- 루트노드가 0이면 모든 자식노드는 0이다.
📝 의사코드
- 숫자를 입력받아 이진수로 바꾼다.
- 이진수의 길이를 구하고, 만들 수 있는 최소 포화 이진트리 개수를 구한다.
- 최소 포하 이진트리 개수 - 현재의 이진트리 = 0이 만들어질 개수
- 0이 만들어질 개수를 현재의 이진트리 왼쪽끝에 추가한다.
- 현재 이진수가 올바른 트리인지 확인한다.
- 루트노드가 1이면 분할정복하여 왼쪽, 오른쪽 각각의 올바른 트리인지 확인한다.
- 루트노드가 0이면 루트노드 기준으로 왼쪽, 오른쪽은 모두 0이 되어야한다. 그렇지 않다면 올바른 트리가 아니다.
💻 코드
def make_binary(number):
if number == 0:
return '0'
temp = ''
while number > 0:
temp += str(number % 2)
number = number // 2
return temp[::-1]
def is_binary(binary):
if len(binary) == 1:
return True
center = len(binary)//2
if binary[center] == '1':
return is_binary(binary[:center]) and is_binary(binary[center+1:])
else:
for l in range(center):
if binary[l] == '1':
return False
for r in range(center+1, len(binary)):
if binary[r] == '1':
return False
return True
def solution(numbers):
answer = []
for number in numbers:
temp = make_binary(number)
h = 0
for i in range(1, int(1e9)):
if pow(2,i) - 1 >= len(temp):
h = pow(2,i) - 1
break
temp2 = '0'* (h - len(temp))
if is_binary(temp2 + temp):
answer.append(1)
else:
answer.append(0)
return answer
🎯 피드백 및 개선사항
- 문제에서 루트노드가 1이면 왼쪽노드집합, 오른쪽노드집합이 올바른 이진트리인지 확인하고, 루트노드가 0이면 자식노드가 모두 0이 되어야하는 조건을 생각해 내는것이 문제의 핵심 포인트이다.
- 높이가 n일때, 이진 포화 트리의 노드의 개수가 2^n -1 이라는것을 파악해 내는것이 핵심 포인트이다.
❓다른사람은 어떻게 풀었을까?
- 문제의 접근 방식은 똑같습니다.
def dnc(num, left, right):
if left == right:
return [True, int(num[left])]
mid = (left + right) // 2
root = int(num[mid])
left_subtree = dnc(num, left, mid - 1)
right_subtree = dnc(num, mid + 1, right)
flag = left_subtree[1] or right_subtree[1]
if flag == 1 and root == 0:
return [0, 0]
return [left_subtree[0] and right_subtree[0], root]
def get_answer(num):
tmp = ''
while num > 0:
tmp = tmp + str(num % 2)
num //= 2
size = 1
while len(tmp) > pow(2, size) - 1:
size += 1
while len(tmp) < pow(2, size) - 1:
tmp += '0'
return int(dnc(tmp, 0, len(tmp) - 1)[0])
def solution(numbers):
answer = [get_answer(num) for num in numbers]
return answer
728x90
'알고리즘 > 프로그래머스' 카테고리의 다른 글
[프로그래머스] 퍼즐조각 채우기 (0) | 2024.04.10 |
---|---|
[프로그래머스] 2023 Kakao Blind Recruitment : 표병합 (0) | 2023.11.22 |
[프로그래머스] 2023 Kakao Blind Recruitment : 이모티콘 할인행사 (1) | 2023.11.21 |
[프로그래머스] 2023 Kakao Blind Recuiment 택배 배달 수거하기 (1) | 2023.11.20 |
[프로그래머스] 2020 Kakao Blind Recuritment : 가사 검색 (1) | 2023.11.18 |