문제 링크
https://leetcode.com/problems/trapping-rain-water/
나의 풀이
소스 코드
from typing import List
class Solution:
def my_solution(self, height: List[int]) -> int:
# 해당 구간의 빗물의 양을 구하는 함수
def get_trapped(elevation: List[int]) -> int:
max_height = min(elevation[0], elevation[-1])
water = 0
for curr in elevation[1:-1]:
water += max_height - curr
return water
# 빈 배열의 경우 0 리턴
if len(height) == 0:
return 0
start, total = 0, 0
# 가장 큰 값의 인덱스 (중복되는 경우 마지막 인덱스)
max_idx = len(height) - height[::-1].index(max(height)) - 1
# 가장 큰 값의 인덱스까지 빗물의 양 계산
for end in range(1, max_idx + 1):
if height[end] >= height[start]:
total += get_trapped(height[start:end + 1])
start = end
# 가장 큰 값의 인덱스가 오른쪽 끝에 존재하거나
# 현재까지 구한 빗물의 양이 0일 경우
# 가장 큰 값의 인덱스부터 끝까지 슬라이싱 후 뒤집어서 새로운 리스트 생성,
# 해당 리스트의 빗물의 양을 계산
if max_idx != len(height) - 1 or total == 0:
left_heights = height[max_idx:][::-1]
start = 0
for end in range(1, len(left_heights)):
if left_heights[end] >= left_heights[start]:
total += get_trapped(left_heights[start:end + 1])
start = end
return total
문제 풀이
1. 투 포인터를 최대로 이동
- 시간 복잡도는 O(n)이다.
소스 코드
from typing import List
class Solution:
def solution1(self, paragraph: str, banned: List[str]) -> str:
# 빈 배열 예외 처리
if not height:
return 0
volume = 0
left, right = 0, len(height) - 1
left_max, right_max = height[left], height[right]
# 투 포인터 이동
while left < right:
left_max, right_max = max(height[left], left_max), max(height[right], right_max)
# 더 높은 쪽을 향해 투 포인터 이동
if left_max <= right_max:
volume += left_max - height[left]
left += 1
else:
volume += right_max - height[right]
right -= 1
return volume
2. 투 포인터를 최대로 이동
- 시간 복잡도는 O(n)이지만, 투 포인터 방식보다 실행 시간이 조금 더 걸린다.
소스 코드
from typing import List
class Solution:
def solution2(self, height: List[int]) -> int:
stack = []
volume = 0
for i in range(len(height)):
# 변곡점(Inflection Point), 즉 현재 높이가 이전보다 더 높을 때
while stack and height[i] > height[stack[-1]]:
# 스택에서 추출
top = stack.pop()
if not len(stack):
break
# 이전과의 차이만큼 물 높이 처리
distance = i - stack[-1] - 1
waters = min(height[i], height[stack[-1]]) - height[top]
volume += distance * waters
stack.append(i)
return volume