Algorithm Problem with Python — 33day
Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it can trap after raining.
각 막대의 너비가 1인 입면도를 나타내는 n개의 음이 아닌 정수가 주어지면 비가 내린 후 얼마나 많은 물을 가둘 수 있는지 계산한다.
제한사항⁵
입출력 예
Example 1:
Input: height = [0,1,0,2,1,0,1,3,2,1,2,1]
Output: 6
Explanation: The above elevation map (black section) is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped.
Example 2:
Input: height = [4,2,0,3,2,5]
Output: 9
이 문제는 투 포인터를 최대로 이동하는 방법과 스택을 쌓는 방법으로 해결할 수 있습니다.
저는 투 포인트를 최대로 이동하는 방법으로 진행했습니다.
먼저 가장 높이가 높은 막대를 살펴보면 예시 1에서 최대 높이가 3이지만 최대 높이라는 역할을 한다면 값에 무관하게 전체 부피에 영향은 끼치지 않습니다.
그저 왼쪽과 오른쪽을 가르는 장벽 역할을 합니다.
가장 높이가 높은 막대를 기준으로 좌우로 투 포인트를 배치하고 기준까지 이동하며 부피를 체크합니다.
기준이 되는 최대 높이 막대까지 각각 좌우 기둥 최대 높이와 현재 높이와의 차이만큼 물 높이를 더해 나가면 됩니다.
class Solution:
def trap(self, height: List[int]) -> int:
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
이번 문제는 상당히 어려웠습니다.
효율적인 풀이법을 못 찾고 높이와 너비 모든 공간을 차례대로 모두 살펴봤으면 0(n²)의 시간복잡도가 걸렸을 것입니다.
이번 풀이를 통해서 해당 문제와 같은 유형에서는 투 포인터나 스택으로 0(n) 풀이가 가능한 것을 알게 되었습니다.
최대 높이 막대가 기준이 되는 점을 통해 좌우로 나눌 수 있었고 좌우 각각에서도 가장 높은 막대와 현재 막대 높이의 차이만큼 물 높이가 생기는 것을 알 수 있었습니다.
복잡한 문제일수록 문제를 잘게 나누어 고민하면 이와 같이 풀어 나갈 수 있으니 복잡함을 단순함으로 나누는 연습이 필요함을 느낄 수 있는 문제였습니다.
Reference