https://programmers.co.kr/learn/courses/30/lessons/64063#
Naive하게 생각하면, 요청이 올때마다 해당 방이 빈방인지 아닌지 check하고, 빈방이 아니라면 방번호를 1씩 늘려가며 빈 방인지 아닌지 확인하는 것이 먼저 떠오를 것이다.
def solution(k, room_number):
answer = []
now = dict()
for num in room_number:
if num not in now:
now[num] = num + 1
else:
while num in now:
num = now[num]
now[num] = num+1
answer.append(num)
return answer
하지만, 요청이 총 200,000개 여서 O(n^2) 이 걸리게 되어 TLE에 걸리게 된다.
방번호를 늘려가면서 빈 방을 찾을 때, 찾은 빈 방을 지금까지 확인했던 방과 연결 시켜, 앞으로 해당 방들에 대한 요청이 들어오면 현재 찾은 빈칸을 바로 반환하게 하면 어떨까? 라는 생각이 들었다.
그래서 현재 요청을 처리하기 위해 확인 했던 방들을 저장하고, 빈 방을 찾은 뒤, 저장된 방들의 다음방을 빈 방으로 연결시켜주는 작업을 했다.
다음은 구현한 코드이다.
import sys
sys.setrecursionlimit(500000)
def solution(k, room_number):
answer = []
now = dict()
for num in room_number:
if num not in now:
now[num] = num + 1
else:
stack = []
while num in now:
num = now[num]
stack.append(num)
now[num] = num+1
for n in stack:
now[n] = num+1
answer.append(num)
return answer
위와 같은 최적화를 하니 통과할 수 있었다.
이런 경로압축은 재귀함수를 통해 구현할 수 있다. Union-Find를 알고 있다면 쉽게 구현할 수 있을 것이다.
다음은 Union-Find로 구현한 코드이다.
import sys
sys.setrecursionlimit(500000)
def solution(k, room_number):
answer = []
now = dict()
def find(a):
if a not in now : return a
else:
now[a] = find(now[a])
return now[a]
def union(a, b):
a = find(a)
b = find(b)
now[a] = b
for number in room_number:
n = find(number)
answer.append(n)
union(number, n+1)
return answer
'알고리즘' 카테고리의 다른 글
BOJ 2437 저울 (0) | 2022.01.21 |
---|---|
2018 KAKAO 자동완성 (0) | 2022.01.19 |
2021 KAKAO 채용연계형 인턴쉽 시험장 나누기 (0) | 2021.12.15 |
2020 KAKAO 인턴쉽 동굴 탐험 (0) | 2021.11.30 |
2020 KAKAO 카카오 인턴쉽 경주로 건설 (0) | 2021.11.30 |