Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 백엔드 부트캠프
- 국비지원
- 내일배움카드
- 국비지원교육
- baekjoon
- 오픈패스
- 오블완
- UXUI기초정복
- 부트캠프
- Spring
- 패스트캠퍼스
- 오픈챌린지
- OPENPATH
- 환급챌린지
- Java
- 디자인챌린지
- UXUIPrimary
- 백준
- 백엔드개발자
- 티스토리챌린지
- 국비지원취업
- 백엔드
- 객체지향
- 디자인강의
- mysql
- 디자인교육
- UXUI챌린지
- KDT
- Be
- 내일배움캠프
Archives
- Today
- Total
군만두의 IT 공부 일지
[백준] 1068번: 트리 (파이썬) 본문
✅문제: 1068번
1068번: 트리
첫째 줄에 트리의 노드의 개수 N이 주어진다. N은 50보다 작거나 같은 자연수이다. 둘째 줄에는 0번 노드부터 N-1번 노드까지, 각 노드의 부모가 주어진다. 만약 부모가 없다면 (루트) -1이 주어진다
www.acmicpc.net
📌개념정리
(1) 트리(Tree)
- 정의: 계층적 관계를 표현하는 비선형 자료구조
- 하나의 루트 노드와 여러 자식 노드들로 구성되며, 노드 간에는 부모-자식 관계가 존재함.
- 트리 구조는 노드와 노드를 연결하는 에지(edge)로 구성되며, 사이클이 존재하지 않음.
- 파이썬에서 트리 사용
- 각 노드의 자식 정보를 저장하기 위해 리스트를 사용할 수 있음.
- 리스트의 각 요소는 해당 인덱스 노드의 자식 노드 인덱스를 저장하는 또 다른 리스트가 될 수 있음.
📌문제풀이
주어진 트리에서 특정 노드를 삭제한 후, 남은 트리의 리프 노드(자식이 없는 노드)의 수를 세는 문제임. 노드는 0부터 N-1까지의 번호로 주어짐.
1. 입력으로 노드의 수와 트리의 구조, 삭제할 노드의 번호를 받음
2. 트리의 각 노드마다 자식 노드의 인덱스를 저장하는 리스트(children)를 초기화
3. 루트 노드를 찾고, 각 노드의 자식 노드를 리스트에 저장
4. 삭제할 노드와 그 자식 노드를 재귀적으로 탐색하여 모든 연결을 제거
5. 삭제 후의 트리에서 루트 노드부터 시작하여 잎 노드의 수를 재귀적으로 계산
# 노드를 재귀적으로 삭제하는 함수
def delete_node_recursive(node):
global children
children[node] = [-1] # 삭제된 노드의 자식 목록을 [-1]로 설정
for i in range(len(children)):
if node in children[i]:
children[i].remove(node)
# 주어진 노드에서 시작하여 잎 노드의 수를 세는 재귀 함수
def count_leaf_nodes(node):
if children[node] == [-1]: # 노드가 삭제된 경우
return 0
if not children[node]: # 자식 노드가 없는 경우, 이 노드는 잎 노드
return 1
count = 0 # 잎 노드의 수
for child in children[node]:
count += count_leaf_nodes(child)
return count
n = int(input()) # 노드의 수
tree = list(map(int, input().split())) # 노드의 부모
delete_node = int(input()) # 삭제할 노드 번호
children = [[] for _ in range(n)] # 각 노드의 자식 노드 인덱스 저장
root = -1 # 루트 노드 인덱스 초기화
for i in range(n):
if tree[i] == -1:
root = i # 루트 노드
else:
children[tree[i]].append(i)
delete_node_recursive(delete_node)
if delete_node == root:
print(0)
else:
print(count_leaf_nodes(root))
코드 실행 과정을 설명하면, 예제 입력 1은 5개의 노드가 있고, 노드 간의 관계, 삭제할 노드 번호가 주어짐.
# 예제 입력 1
5
-1 0 0 1 1
2
1) 트리 구조 파악
노드의 부모를 인덱스로 나타낸 배열을 통해 트리를 구성함.
- 인덱스 0: 부모가 -1(루트 노드)
- 인덱스 1, 2: 부모가 0
- 인덱스 3, 4: 부모가 1
2) 초기 트리 구조
0
/ \
1 2
/ \
3 4
3) 노드 삭제
노드 2를 삭제함.
0
/
1
/ \
3 4
4) 리프 노드 계산
남은 트리에서 리프 노드를 계산함. 노드 3과 노드 4는 자식이 없으므로 리프 노드임. 따라서 리프 노드의 수인 2를 출력함.
# 예제 출력 1
2
📌후기
- 트리 구조를 파이썬의 리스트를 활용하여 간단하게 표현하는 연습이 필요함.
- 재귀 함수를 사용하여 트리의 노드를 삭제하고 잎 노드의 수를 세는 로직을 구현하는 과정이 어려웠음. 노드 삭제 후에도 올바른 트리 구조를 유지하도록 고려함.
📌참고자료
1) 위키독스, "07. 파이썬으로 트리 구현하기", https://wikidocs.net/193702
'코딩테스트 > 백준' 카테고리의 다른 글
[백준] 17218번: 비밀번호 만들기 (파이썬) (0) | 2024.04.28 |
---|---|
[백준] 1717번: 집합의 표현 (파이썬) (0) | 2024.04.25 |
[백준] 14502번: 연구소 (파이썬) (1) | 2024.04.22 |
[백준] 7795번: 먹을 것인가 먹힐 것인가 (파이썬) (0) | 2024.04.17 |
[백준] 2230번: 수 고르기 (파이썬) (0) | 2024.04.14 |
Comments