|
1 |
| -////////////////////////////////////////////////////////////////////////////// |
2 |
| -// Time: O(n) Space: O(1) One iteration. |
3 |
| -////////////////////////////////////////////////////////////////////////////// |
4 |
| - |
5 | 1 | /**
|
6 |
| - * @param {!Array<number>} heights |
| 2 | + * https://leetcode.com/problems/trapping-rain-water/ |
| 3 | + * Time O(N) | Space O(1) |
| 4 | + * @param {number[]} height |
7 | 5 | * @return {number}
|
8 | 6 | */
|
9 |
| -function trap(heights) { |
10 |
| - let l = 0; |
11 |
| - let r = heights.length - 1; |
12 |
| - let lMax = 0; |
13 |
| - let rMax = 0; |
14 |
| - let total = 0; |
15 |
| - |
16 |
| - while (l < r) { |
17 |
| - if (heights[l] < heights[r]) { |
18 |
| - if (heights[l] >= lMax) { |
19 |
| - lMax = heights[l]; |
20 |
| - } else { |
21 |
| - total += lMax - heights[l]; |
22 |
| - } |
23 |
| - ++l; |
24 |
| - } else { |
25 |
| - if (heights[r] >= rMax) { |
26 |
| - rMax = heights[r]; |
27 |
| - } else { |
28 |
| - total += rMax - heights[r]; |
29 |
| - } |
30 |
| - --r; |
| 7 | + var trap = function(height) { |
| 8 | + let [ left, right ] = [ 0, (height.length - 1) ]; |
| 9 | + let [ maxLeft, maxRight, area ] = [ 0, 0, 0 ]; |
| 10 | + |
| 11 | + while (left < right) { |
| 12 | + const [ leftHeight, rightHeight ] = getHeights(height, left, right); |
| 13 | + const [ leftWindow, rightWindow ] = getWindows(height, left, maxLeft, right, maxRight); |
| 14 | + |
| 15 | + const isRightGreater = leftHeight <= rightHeight; |
| 16 | + if (isRightGreater) { |
| 17 | + if (hasNewMax(maxLeft, leftHeight)) maxLeft = leftHeight; |
| 18 | + else area += leftWindow; |
| 19 | + |
| 20 | + left++; |
31 | 21 | }
|
32 |
| - } |
33 | 22 |
|
34 |
| - return total; |
35 |
| -} |
| 23 | + const isRightLess = rightHeight < leftHeight; |
| 24 | + if (isRightLess) { |
| 25 | + if (hasNewMax(maxRight, rightHeight)) maxRight = rightHeight; |
| 26 | + else area += rightWindow; |
36 | 27 |
|
37 |
| -////////////////////////////////////////////////////////////////////////////// |
38 |
| -// Time: O(n) Space: O(n) Two iterations (one main loop and one stack). |
39 |
| -////////////////////////////////////////////////////////////////////////////// |
40 |
| - |
41 |
| -/** |
42 |
| - * @param {!Array<number>} heights |
43 |
| - * @return {number} |
44 |
| - */ |
45 |
| -function trap(heights) { |
46 |
| - const stack = []; |
47 |
| - let total = 0; |
48 |
| - |
49 |
| - for (let i = 0; i < heights.length; ++i) { |
50 |
| - while (stack.length && heights[i] > heights[top(stack)]) { |
51 |
| - const j = stack.pop(); |
52 |
| - |
53 |
| - if (!stack.length) { |
54 |
| - break; |
55 |
| - } |
56 |
| - |
57 |
| - const k = top(stack); |
58 |
| - const spread = i - k - 1; |
59 |
| - const height = Math.min(heights[i], heights[k]) - heights[j]; |
60 |
| - total += spread * height; |
| 28 | + right--; |
61 | 29 | }
|
62 |
| - |
63 |
| - stack.push(i); |
64 | 30 | }
|
65 | 31 |
|
66 |
| - return total; |
67 |
| -} |
68 |
| - |
69 |
| -/** |
70 |
| - * @param {!Array<*>} stack |
71 |
| - * @return {*} |
72 |
| - */ |
73 |
| -function top(stack) { |
74 |
| - return stack[stack.length - 1]; |
75 |
| -} |
| 32 | + return area; |
| 33 | +}; |
76 | 34 |
|
77 |
| -////////////////////////////////////////////////////////////////////////////// |
78 |
| -// Time: O(n) Space: O(n) Three iterations (two main loop and one stack). |
79 |
| -////////////////////////////////////////////////////////////////////////////// |
| 35 | +const hasNewMax = (max, height) => max < height; |
80 | 36 |
|
81 |
| -/** |
82 |
| - * @param {!Array<number>} heights |
83 |
| - * @return {number} |
84 |
| - */ |
85 |
| -function trap(heights) { |
86 |
| - let valley = []; |
87 |
| - let barrier = 0; |
88 |
| - let trapped = 0; |
| 37 | +const getHeights = (height, left, right) => [ height[left], height[right] ]; |
89 | 38 |
|
90 |
| - for (const height of heights) { |
91 |
| - if (height >= barrier) { |
92 |
| - while (valley.length) { |
93 |
| - trapped += barrier - valley.pop(); |
94 |
| - } |
95 |
| - barrier = height; |
96 |
| - } else { |
97 |
| - valley.push(height); |
98 |
| - } |
99 |
| - } |
100 |
| - |
101 |
| - valley.reverse(); |
102 |
| - valley.push(barrier); |
103 |
| - heights = valley; |
104 |
| - valley = []; |
105 |
| - barrier = 0; |
106 |
| - |
107 |
| - for (const height of heights) { |
108 |
| - if (height >= barrier) { |
109 |
| - while (valley.length) { |
110 |
| - trapped += barrier - valley.pop(); |
111 |
| - } |
112 |
| - barrier = height; |
113 |
| - } else { |
114 |
| - valley.push(height); |
115 |
| - } |
116 |
| - } |
| 39 | +const getWindows = (height, left, maxLeft, right, maxRight) => { |
| 40 | + const [ leftHeight, rightHeight ] = getHeights(height, left, right); |
| 41 | + const [ leftWindow, rightWindow ] = [ (maxLeft - leftHeight), (maxRight - rightHeight) ]; |
117 | 42 |
|
118 |
| - return trapped; |
| 43 | + return [ leftWindow, rightWindow ]; |
119 | 44 | }
|
0 commit comments