[Swift]LeetCode42. 接雨水 | Trapping Rain Water

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公衆號:山青詠芝(shanqingyongzhi)
➤博客園地址:山青詠芝(https://www.cnblogs.com/strengthen/
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:http://www.javashuo.com/article/p-qladodck-me.html 
➤若是連接不是山青詠芝的博客園地址,則多是爬取做者的文章。
➤原文已修改更新!強烈建議點擊原文地址閱讀!支持做者!支持原創!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★html

Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.git


The above elevation map 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. Thanks Marcos for contributing this image!github

Example:算法

Input: [0,1,0,2,1,0,1,3,2,1,2,1]
Output: 6

給定 n 個非負整數表示每一個寬度爲 1 的柱子的高度圖,計算按此排列的柱子,下雨以後能接多少雨水。編程

上面是由數組 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度圖,在這種狀況下,能夠接 6 個單位的雨水(藍色部分表示雨水)。 感謝 Marcos 貢獻此圖。數組

示例:微信

輸入: [0,1,0,2,1,0,1,3,2,1,2,1]
輸出: 6

【雙指針】12ms
咱們可能會想到在一次迭代中作某種方式,而不是單獨計算左右部分。
從圖中的動態編程方法來看,只要注意
right_max left_max ]right_max[一世]>left_max[一世] (從元素0到6),被困水取決於left_max,相似狀況 left_max right_max ]left_max[一世]>right_max[一世](從要素8到11)。
所以,咱們能夠說若是一端有一個較大的條(如右圖),咱們能夠確保被困的水將取決於當前方向(從左到右)的條形高度。
一旦咱們發現另外一端(右)的條形較小,咱們就會開始以相反的方向(從右到左)進行迭代。
咱們必須堅持
left_maxleft_max 和 right_maxright_max 在迭代期間,但如今咱們能夠使用2個指針在一次迭代中完成,在二者之間切換。

算法app

  • Initialize \text{left}left pointer to 0 and \text{right}right pointer to size-1
  • While \text{left}&lt; \text{right}left<right, do:
    • If \text{height[left]}height[left] is smaller than \text{height[right]}height[right]
    • If height[left]>=left_maxheight[left]>=left_max, update left_maxleft_max
      • Else add left_maxheight[left]left_max−height[left] to \text{ans}ans
      • Add 1 to \text{left}left.
    • Else
      • If height[right]>=right_maxheight[right]>=right_max, update right_maxright_max
      • Else add right_maxheight[right]right_max−height[right] to \text{ans}ans
      • Subtract 1 from \text{right}right.
 1 class Solution {
 2     func trap(_ height: [Int]) -> Int {
 3         var leftMax = 0, rightMax = 0
 4         var leftPointer = 0, rightPointer = height.count - 1
 5         var trappedWater = 0
 6         
 7         while leftPointer < rightPointer {
 8             if height[leftPointer] < height[rightPointer] {
 9                 if height[leftPointer] > leftMax {
10                     leftMax = height[leftPointer]
11                 } else {
12                     trappedWater += leftMax - height[leftPointer]
13                 }
14                 leftPointer += 1
15             } else {
16                  if height[rightPointer] > rightMax {
17                     rightMax = height[rightPointer]
18                 } else {
19                     trappedWater += rightMax - height[rightPointer]
20                 }
21                 rightPointer -= 1
22             } 
23         }
24         return trappedWater
25     }
26 }

【動態編程】 16msthis

 1 class Solution {
 2   func trap(_ height: [Int]) -> Int {
 3     var leftMax = [Int]()
 4     var rightMax = [Int]()
 5     var maxL = 0
 6     var maxR = 0
 7     for i in 0..<height.count {
 8       if maxL < height[i] {
 9         maxL = height[i]
10       }
11       leftMax.append(maxL)
12       if maxR < height[height.count - 1 - i] {
13         maxR = height[height.count - 1 - i]
14       }
15       rightMax.append(maxR)
16     }
17     rightMax.reverse()
18     var result = 0
19     for i in 0..<height.count {
20       let wall = max(min(leftMax[i], rightMax[i]), height[i])
21       result += wall - height[i]
22     }
23     return result
24   }
25 }

【暴力破解】28msspa

 1 class Solution {
 2     func trap(_ height: [Int]) -> Int {
 3         if height.count <= 0 {
 4             return 0
 5         }
 6         var maxL = height[0]
 7         var rights : Array = Array<Int>(repeating: 0, count: height.count)
 8         var result = 0
 9         var maxR = 0
10         
11         for i in height.enumerated().reversed() {
12             if height[i.offset] > maxR {
13                 maxR = i.element
14                 rights[i.offset] = maxR
15             }else {
16                 rights[i.offset] = maxR
17             }
18         }
19         
20         for i in 0..<height.count {
21             if height[i] > maxL {
22                 maxL = height[i]
23             }
24             result += max(min(maxL, rights[i]) - height[i],0)
25         }
26         
27         
28         return result
29     }
30 }

【暴力破解】44ms

 1 class Solution {
 2     func trap(_ height: [Int]) -> Int {
 3         guard height.count > 2 else { return 0 }
 4         var res: Int = 0
 5         var leftMax = Array(repeating: 0, count: height.count)
 6         var rightMax = Array(repeating: 0, count: height.count)
 7     
 8         leftMax[0] = height[0]
 9         for i in 1..<height.count {
10             leftMax[i] = max(leftMax[i - 1], height[i])
11         }
12         
13         rightMax[height.count - 1] = height[height.count - 1]
14         for i in (0..<height.count - 1).reversed() {
15             rightMax[i] = max(rightMax[i + 1], height[i])
16         }
17     
18         for i in 1..<height.count - 1 {
19             res += min(leftMax[i], rightMax[i]) - height[i]
20         }
21         
22         return res
23     }
24 }

 【使用堆棧】64ms

 1 class Solution {
 2     func trap(_ height: [Int]) -> Int {
 3         var stack = Stack<Int>()
 4         
 5         var ans = 0
 6         
 7         var current = 0
 8         
 9         while current < height.count {
10             while !stack.isEmpty && height[current] > height[stack.peek()] {
11                 let top = stack.pop()
12 
13                 if stack.isEmpty {
14                     break
15                 }
16                 
17                 let distance = current - stack.peek() - 1
18                 
19                 let height = min(height[current], height[stack.peek()]) - height[top]
20                 
21                 ans += distance * height
22             }
23             stack.push(current)
24             current += 1
25         }
26         
27         return ans
28     }
29 }
30 
31 class Stack<T> {
32     private var arr = [T]()
33     
34     var isEmpty: Bool {
35         return arr.isEmpty
36     }
37     
38     func peek() -> T {
39         return arr.last!
40     }
41     
42     func push(_ t: T) {
43         arr.append(t)
44     }
45     
46     func pop() -> T {
47         return arr.removeLast()
48     }
49 }
相關文章
相關標籤/搜索