Your country has an infinite number of lakes. Initially, all the lakes are empty, but when it rains over the nth lake, the nth lake becomes full of water. If it rains over a lake that is full of water, there will be a flood. Your goal is to avoid floods in any lake.
Given an integer array rains where:
rains[i] > 0 means there will be rains over the rains[i] lake.
rains[i] == 0 means there are no rains this day and you can choose one lake this day and dry it.
Return an array ans where:
ans.length == rains.length
ans[i] == -1 if rains[i] > 0.
ans[i] is the lake you choose to dry in the ith day if rains[i] == 0.
If there are multiple valid answers return any of them. If it is impossible to avoid flood return an empty array.
Notice that if you chose to dry a full lake, it becomes empty, but if you chose to dry an empty lake, nothing changes.
당신의 나라에는 무한히 많은 호수가 있습니다. 처음에는 모든 호수가 비어 있지만, n번째 호수 위로 비가 내리면 그 호수는 물로 가득 찹니다. 이미 물로 가득 찬 호수에 비가 내리면 홍수가 발생합니다. 당신의 목표는 어떤 호수에서도 홍수가 발생하지 않도록 하는 것입니다.
정수 배열 rains가 주어졌을 때:
rains[i] > 0은 rains[i]번 호수에 비가 내린다는 것을 의미합니다.
rains[i] == 0은 그날 비가 내리지 않아 당신이 원하는 하나의 호수를 선택해 물을 말릴 수 있다는 것을 의미합니다.
다음 조건을 만족하는 배열 ans를 반환하세요:
ans.length == rains.length
rains[i] > 0일 경우 ans[i] == -1
rains[i] == 0일 경우 ans[i]는 그날 당신이 물을 말릴 호수의 번호입니다. 단, 말릴 수 있는 물로 가득 찬 호수가 없을 경우에는 반드시 1번 호수를 말립니다.
유효한 답이 여러 개일 경우 그중 하나를 반환하면 됩니다. 홍수를 피할 수 없는 경우 빈 배열을 반환하세요.만약 당신이 물로 가득 찬 호수를 말리기로 선택하면 그 호수는 비게 되지만, 이미 비어 있는 호수를 말리기로 선택하면 아무 변화도 일어나지 않습니다.
[1,2,0,0,2,1]
[-1,-1,2,1,-1,-1]
해당 문제를 풀기 위해선 반드시 필요한 자료형이 3가지가 있다.
최종적으로 1번 SortedList에 남은 값들에 대해 ans에 1로 채우면 된다.
from sortedcontainers import SortedList
class Solution:
def avoidFlood(self, rains: List[int]) -> List[int]:
N = len(rains) # 입력 배열 rains의 길이
# 0이 나타나는 인덱스를 정렬된 상태로 저장 (SortedList로 0의 위치를 추적)
zeroes = SortedList([i for i, v in enumerate(rains) if v == 0])
# 호수 번호를 키로, 비가 내린 시간을 값으로 저장하는 딕셔너리
placement = dict()
# 정답을 저장할 배열, 초기값은 -1로 채움 (rains와 동일한 길이)
ans = [-1] * N
# rains 배열을 순회하며 각 인덱스와 값을 처리
for i, v in enumerate(rains):
if v != 0: # 비가 내린 경우 (호수 번호가 0이 아닌 경우)
if v not in placement: # 해당 호수에 처음으로 비가 내린 경우
# 호수 번호와 비가 내린 시간을 딕셔너리에 저장
placement[v] = i
else: # 해당 호수에 이미 비가 내린 적이 있는 경우
# 이전 비가 내린 시간과 현재 시간을 가져옴
left_value = placement[v]
right_value = i
# SortedList에서 이전 비와 현재 비 사이의 0 인덱스를 찾기 위해 이진 탐색
left = bisect_left(zeroes, left_value) # 이전 비 이후 첫 0의 위치
right = bisect_left(zeroes, right_value) # 현재 비 이전 마지막 0의 위치
# 두 위치 사이의 0의 개수 계산
count = right - left
if count == 0: # 0이 없으면 물을 말릴 기회가 없으므로 불가능
return []
# 사용 가능한 첫 번째 0의 인덱스를 선택
target = zeroes[left]
# 해당 0의 인덱스를 SortedList에서 제거
zeroes.remove(target)
# 정답 배열에서 해당 인덱스에 호수 번호를 기록 (물을 말린 호수)
ans[target] = v
# 딕셔너리의 호수 시간을 현재 시간으로 갱신
placement[v] = i
# 남은 0의 인덱스에 대해 임의로 1을 채움 (아무 호수나 말릴 수 있음)
for z in zeroes:
ans[z] = 1
# 최종 정답 배열 반환
return ans