React

42. Trapping Rain Water

Hard
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.
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.
Plain Text
복사
Example 2:
Input: height = [4,2,0,3,2,5] Output: 9
Plain Text
복사
Constraints:
n == height.length
1 <= n <= 2 * 104
0 <= height[i] <= 105

My solution

2차원 배열으로 1과 0으로 채워진 배열을 만든다. indexOf와 lastIndexOf를 사용해서 행에서 처음 만나는 1과 마지막 만나는 1의 인덱스가 다르다면 빗물을 채울 수 있다고 예상했다. 이때 이 두 인덱스를 slice()의 범위에 넣어서 배열을 자른다음 filter로 잘라서 길이를 구했다. 그런데 이렇게 하면 처음으로 시간 초과가 났다.
투포인터를 적용하든 해서 이중 for문이 없어야 하고 시간복잡도가 O(n^2)되서는 안된다.
10^4만큼의 인풋이 들어오는데 제곱을 하면 시간초과가 된다.

Code

const trap = function (height) { // 투포인터의 lt = 0, rt = length-1; 기본값 let left = 0; let right = height.length - 1; // 누적시킬 물의 양 let maxWater = 0; // 왼쪽 기준 높이값(들어온 요소의 높이랑 빼주기 위해서 필요) let leftMax = height[left]; // 오른쪽 기준 높이값(들어온 요소의 높이랑 빼주기 위해서 필요) let rightMax = height[right]; // 왼쪽에서 오른쪽, 범위 조절하면서 탐색 while (left < right) { // 배열에서 왼쪽 높이보다 오른쪽 높이가 크면? // -> mid는 바로 해도 lt, rt는 어떤 조건에 따라 업데이트됨. // 그리고 그 업데이트된 인덱스로 값에 접근해서 max에서 빼 누적함 // -> 다음 값은 지금 높이가 더 크다면 그걸 기준으로 해야 되므로 업데이트함 if (height[left] < height[right]) { left++; maxWater += Math.max(0, leftMax - height[left]); leftMax = Math.max(leftMax, height[left]); } else { right--; maxWater += Math.max(0, rightMax - height[right]); rightMax = Math.max(rightMax, height[right]); } } return maxWater; };
JavaScript
복사