프로그래머스[programmers] - 표현 가능한 이진 트리(Kotlin)[LV3]

2023. 11. 1. 18:32· CodingTest/Programmers
목차
  1. 문제
  2. 문제 풀이
  3. 전체 코드

문제

https://school.programmers.co.kr/learn/courses/30/lessons/150367#

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

문제 풀이

문제를 읽어도 전혀 이해가 가지 않았다. 주어진 이진트리가 뭐지? 무슨 규칙이 있는 건가? 싶어서

무작정 문제에 대한 예시를 그려보았다.

 

우선 문제에 대한 예시로 나온 숫자들을 2진수로 바꾸면 다음과 같다.

그리고 문제에서 포화 이진트리로 생성해야 했기에, 0을 채워줬다.

포화 이진트리는 깊이가 n일때 노드의 개수는 2ⁿ -1으로 맞춰줘야 한다.

따라서 42와 63 모두 깊이가 3이지만 노드의 개수가 6개였기에, 7개로 맞춰주기 위해서 0을 채워줬다.

보면 5와 95는 이진트리로 만들기 불가능하다고 예시에서 주어졌다.

 

문제에서 숫자는 왼쪽에서부터 채워진다고 했기 때문에 다음과 같은 트리로 만들 수 있다.

해당 숫자들을 이진트리로 표현하지 못하는 이유는 부모가 0이기 때문이라고 생각했다.

즉 부모가 0이면 이진트리로 표현하지 못한다!라는 사실을 예시를 통해서 얻을 수 있다.

 

하지만 문제를 풀다가 틀려서 다른 분의 풀이를 보니 부모가 0이라도 자식들이 모두 0이라면 이진트리로 표현이 가능하다는 것이었다.

아무리 봐도 예를 통해서 추출할 수 없는 사실인데.. 좀 궁금하다.

 

아무튼 그럼 우리는 이진트리로 만들지 못하는 경우에 대해서 정리할 수 있다.

  1. 부모가 0인데 자식이 1이 포함되어 있는 경우

해당 경우만 제외하면 모두 이진트리로 표현이 가능하다.

 

이러한 배경지식을 가지고 이제 문제를 풀면 된다.

 

우선 입력받은 숫자를 2진수로 바꿔줘야 한다.

해당 과정은 2로 계속 나누면서 나머지를 채워주면 될 것이다.

여기서 주의할 점은 해당 과정에서 2진수 배열이 거꾸로 형성되기 때문에, 뒤집어주거나 나중에 작업할 때 계속 뒤집어서 해줘야 한다.

나는 여기서 reversed()를 사용해서 처음부터 뒤집은 2진수 문자열을 반환했다.

그런 다음 포화트리로 만들어줬다.

이진수 문자열의 길이에 따라서 층을 정할 수 있기 때문에 포화트리로 만들어줬다.

당연하게도 남는 자리는 0을 채워야 한다.

앞에서부터 채워줘야 하기에 StringBuilder()를 사용했다.

 

다음은 이제 이진수 문자열을 트리형태로 쪼개주는 작업이다.

해당 작업은 분할정복으로 해도 되고, 실제 트리를 만들어서 탐색을 진행해도 되지만, 분할정복으로 하는 것이 한 번에 할 수 있기 때문에 그렇게 진행했다.

방법은 간단하다.

  1. 문자열을 가운데로 쪼갠다.
  2. 여기서 가운데는 root가 되고, 0부터 root-1까지가 왼쪽 서브트리이고, root+1부터 끝까지 오른쪽 서브트리를 형성할 것이다.
  3. 그렇다면 왼쪽 서브트리를 다시 재귀함수로 호출하고, 오른쪽 서브트리를 다시 재귀 함수로 호출해서 검사를 진행한다.
  4. 재귀함수가 true를 반환하는 조건은 아래와 같다.
    • 길이가 1일 경우
    • 1을 포함하지 않는 경우 -> 위에서 설명한 부모가 0이고, 자식이 0인 경우
    • 루트가 1이고, 왼쪽 서브트리, 오른쪽 서브트리의 결과가 true일 경우
  5. 트리를 만들 수 있다면 1이고, 아니라면 0을 넣어준다.

 

전체 코드

import java.io.*
import java.lang.*
class Solution {
fun solution(numbers: LongArray): IntArray {
var answer = IntArray(numbers.size) { 0 }
for (i in 0 until numbers.size) {
var str = makeBinaryNumber(numbers[i]) // 이진수로 표현
str = makeFullTree(str) //포화트리로 표현
if (str.length == 1 && str == "0") {
answer[i] = 0
continue
}
if (isEnabledFullBinaryTree(str)) { //이진 트리 가능
answer[i] = 1
} else { //이진트리 불가능
answer[i] = 0
}
}
return answer
}
fun makeBinaryNumber(number: Long): String { //Long을 이진수로 표현함
var result = StringBuilder()
var num = number
if (num == 0L) return "0"
while (num > 0) { //이진수로 만들기
result.append(num % 2) //나머지를 계속 박기
num /= 2
}
return result.toString().reversed() //뒤집어주기
}
fun makeFullTree(number: String): String { //노드의 개수는 2^n - 1 개. 꽉곽 채워준다.
var zero = StringBuilder()
var n = 2
while (true) {
if (number.length <= n - 1) break
n *= 2
}
for (i in 0 until n - 1 - number.length) { // 포화 이진트리로 만들어주기.
zero.append("0")
}
return zero.append(number).toString()
}
fun isEnabledFullBinaryTree(number: String): Boolean {
if (number.length == 1 || !number.contains("1")) return true //길이가 1이거나, 1을 포함하지 않는 경우는 트리 형성 가능
val root = number.length / 2 //문자열의 중간
val left = number.substring(0, root) //왼쪽 0~root-1까지
val right = number.substring(root + 1, number.length) //root+1부터 끝까지
if (number[root] == '1' && isEnabledFullBinaryTree(left) && isEnabledFullBinaryTree(right))
return true
return false
}
}
저작자표시 (새창열림)

'CodingTest > Programmers' 카테고리의 다른 글

프로그래머스[programmers] - 섬 연결하기(Kotlin)[LV3]  (0) 2024.03.07
프로그래머스[programmers] - k진수에서 소수 개수 구하기(Kotlin)[LV3]  (0) 2023.11.23
프로그래머스[programmers] - 경주로 건설(Kotlin)[LV3]  (0) 2023.11.01
프로그래머스[programmers] - 보석쇼핑(Kotlin)[LV3]  (0) 2023.10.31
프로그래머스[programmers] - 순위검색(Kotlin)[LV2]  (0) 2023.10.30
  1. 문제
  2. 문제 풀이
  3. 전체 코드
'CodingTest/Programmers' 카테고리의 다른 글
  • 프로그래머스[programmers] - 섬 연결하기(Kotlin)[LV3]
  • 프로그래머스[programmers] - k진수에서 소수 개수 구하기(Kotlin)[LV3]
  • 프로그래머스[programmers] - 경주로 건설(Kotlin)[LV3]
  • 프로그래머스[programmers] - 보석쇼핑(Kotlin)[LV3]
재한
재한
안녕하세요 💻
재한
짜이한
전체
오늘
어제
  • 분류 전체보기 (504)
    • Skils (118)
      • Android (52)
      • C++ (5)
      • Kotlin (36)
      • Algorithm (24)
      • Server (1)
    • CodingTest (228)
      • Programmers (45)
      • Baekjoon (183)
    • Experience (8)
      • 후기(코딩테스트,프로그램,프로젝트) (8)
    • Computer Science (70)
      • Design Pattern (2)
      • OOP (2)
      • Computer Architecture (14)
      • OS (2)
      • Software Engineering (3)
      • DataBase (8)
      • Network (39)
    • 학교 (75)
      • R프로그래밍 (26)
      • 회계와 사회생활 (17)
      • 컴퓨터학개론 (20)
      • it기술경영개론 (12)

블로그 메뉴

  • 홈
  • 태그
  • 카테고리
  • 글쓰기
  • 설정

인기 글

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
재한
프로그래머스[programmers] - 표현 가능한 이진 트리(Kotlin)[LV3]
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.