2024. 1. 18. 15:29ㆍ코딩 테스트/파이썬 알고리즘 인터뷰
42. leetcode Trappong Rain Water
높이를 입력받아 비 온 후 얼마나 많은 물이 쌓일 수 있는지 계산하라
예제1
입력
[0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]
출력
6
풀이
빗물은 가운데를 기준으로 양쪽에서 기둥의 높이가 작은 쪽을 기준으로 쌓인다. 가운데 기둥이 크기와는 상관 없이 양쪽 기둥의 높이에 따라 빗물의 높이가 결정되는 것이다. 이 문제를 풀기 위해 다음 순서대로 빗물이 쌓이는 순서를 정리해본다.
기둥 크기 배열을 heights라 하고 양쪽 기둥의 위치를 각각 L, R이라고 한다. h[L], h[R] 크기를 max_L, max_R에 저장한 후 양쪽 기둥 중에서 작은 쪽의 기둥을 방향에서 높은 기동 방향으로 순차적으로 기둥의 높이를 계산하며 빗물을 채워나간다.
다음과 같이 max_L < max_R인 경우 L->R 방향으로 빗물을 채워나간다.
만약 L~R 사이 기둥의 높이가 max_L보다 작다면 각 빗물의 높이는 다음과 같이 max_L 보다 작은 값으로 채워진다.
L->R 방향으로 진행 중 heights[L] > max_L인 기둥이 존재할 경우에는 max_L값을 갱신하고 갱신된 max_L 값을 기준으로 같은 방향으로 빗물 값을 계산해 나간다.
heights[L] > max_R인 기둥을 만난 경우 빗물은 더 이상 왼쪽 기둥을 기준으로 채워지지 않고 높이가 더 작은 오른쪽 기둥을 기준으로 채워지게 된다. R->L 방향으로 빗물을 채워나간다.
동일하게 R->L 진행 중 height[R] > max_L인 경우 L->R 방향으로 진행한다.
빗물의 총량을 volume이라고 했을 때 진행 방향별 volume은 다음과 같이 계산하고
#L->R 방향일 경우
volume += max_left - height[L]
#R->L 뱡항일 경우
volume += max_right - height[R]
max_L, max_R 크기에 따라 다음 코드에 따라 volume 계산 및 좌, 우 포인터 위치를 이동한다.
if max_left <= max_right:
#L->R 방향일 경우
volume += max_left - height[left]
left += 1
else:
#R->L 뱡항일 경우
volume += max_right - height[right]
right -= 1
이렇게 빗물을 채워가는 것을 L < R이 될 때까지 반복하며, 전체 코드는 다음과 같다.
전체 코드
def trap(self, height):
left, right = 0, len(height) - 1
max_left = max_right = 0
volume = 0
while left < right:
max_left = max(max_left, height[left])
max_right = max(max_right, height[right])
if max_left <= max_right:
volume += max_left - height[left]
left += 1
else:
volume += max_right - height[right]
right -= 1
return volume
빗물의 총량을 volume으로 하였으며, 진행 방향에 따라 max_left - height[left], max_right - height[right]값을 더하여 구하였다.
'코딩 테스트 > 파이썬 알고리즘 인터뷰' 카테고리의 다른 글
Python 알고리즘 인터뷰 - 문제15. 역순 연결 리스트 (0) | 2024.01.19 |
---|---|
Python 알고리즘 인터뷰 - 문제9 세수의 합 (0) | 2024.01.18 |
Python 알고리즘 인터뷰 - 문제7 두 수의 합 (0) | 2024.01.18 |
Python 알고리즘 인터뷰 - 문제6 가장 긴 팰린드롬 부분 문자열 (0) | 2024.01.18 |
Python 알고리즘 인터뷰 - 문제5 그룹 애너그램 (0) | 2024.01.18 |