LeetCode傳送門 https://leetcode.com/problems/trapping-rain-water/ios
目標:找出積木能容納的水的「面積」,如圖中黑色部分是積木,藍色爲可容納水的部分git
假設:積木寬度均爲1github
輸入:各個積木的高度app
輸出:全部積木能容納水的「面積」ide
1. 逐一求積木的間隔彷佛不太容易。特別對於圖中3-7積木間的容積,若是能夠先求底部(4-6間)的容積,當求解上層(3-7)的容積時,還須要作額外的處理,如減掉底部的高度。spa
2. 既然如此,能否先求出3-7間總體的容積,再將兩積木之間的積木面積(四、五、6)減去,便可得這個區域的容積?3d
3. 那麼問題轉換成了,已知一個積木,如何尋找下一個積木,並計算這個兩積木間的容積code
4. 嘗試一,尋找一個至少不比當前積木低的積木,做爲下一個積木,如圖例子爲當前積木3,下一個積木7。那麼之間的容積如何計算呢,簡單,積木3的高度乘以兩積木間的間隔寬度,再減去,積木3與積木7之間的積木(四、五、6)面積。blog
5. 問題:下次迭代從何開始?上一個例子,能夠從積木7繼續算起。然而若是找不到相應的積木呢,那麼從積木3的下一個積木4開始。leetcode
6. 看起來,彷佛正確。因而乎,開始寫代碼了。然而第一次提交就獻給了WA(/(ㄒoㄒ)/~~)
7. 錯誤的狀況,若是當前的積木是一個特別高的積木,後繼找不到更高的積木,然而實際上之間是可能有容積的!不贅述了,補救思路是:在尋找更高的積木的同時,記錄當前找到的最高的積木。若是沒有找到更高的積木,使用當前找到的最高的積木做爲下一個積木,並計算容積。
迭代的過程
1. 尋找下一個至少不比當前積木低的積木,尋找的同時,記錄當前找到的最高的積木高度
2. 若是找到,則計算兩積木之間的容積(計算過程見思考過程2)
3. 若是沒有找到,則計算當前積木與當前找到的最高的積木之間的容積
4. 當前積木設置爲找到的積木(多是2或3的狀況),繼續迭代
O(n)
1 #include <iostream> 2 #include <vector> 3 4 using namespace std; 5 6 class Solution { 7 public: 8 int trap(vector<int>& height) { 9 if (height.size() == 0) { 10 return 0; 11 } 12 13 int water = 0; 14 int preIndex = 0; 15 int preHeight = 0; 16 17 // 找到第一個高度非0的bar 18 while (preIndex < height.size() - 1 && height[preIndex] == 0) { 19 ++preIndex; 20 } 21 22 if (preIndex == height.size() - 1) { 23 return 0; 24 } 25 26 // 遍歷 27 while (preIndex < height.size()) { 28 preHeight = height[preIndex]; 29 30 // 尋找更高的或相等的bar 31 // 同時記錄遍歷過的最高的bar 32 // 若是尋找不到更高的或相等的bar時,使用記錄值計算 33 int next = preIndex + 1; 34 int minHeight = 0; 35 int minIndex = next; 36 37 while (next < height.size() && height[next] < preHeight) { 38 if (height[next] > minHeight) { 39 minHeight = height[next]; 40 minIndex = next; 41 } 42 ++next; 43 } 44 45 // 若是找到 46 if (next != height.size()) { 47 water += (preHeight * (next - preIndex - 1)); // 計算總面積 48 49 for (int i = preIndex + 1; i < next; ++i) { // 減去中間bar面積 50 water -= height[i]; 51 } 52 53 preIndex = next; // 從找到的bar開始下一次的迭代 54 } else { 55 water += (minHeight * (minIndex - preIndex - 1)); // 計算總面積 56 57 for (int i = preIndex + 1; i < minIndex; ++i) { // 減去中間bar面積 58 water -= height[i]; 59 } 60 61 preIndex = minIndex; // 從次高的bar開始 62 } 63 } 64 65 return water; 66 } 67 }; 68 69 int main(int argc, char const *argv[]) { 70 Solution solution; 71 vector<int> height = {0,1,0,2,1,0,1,3,2,1,2,1}; 72 cout << solution.trap(height) << endl; 73 return 0; 74 }
大年初一!祝你們猴年快樂啦,已經工做的童鞋升職加薪,要實習、找工做的童鞋offer多多~博主今年也要面對找實習、找工做的人生大事兒了。很久沒寫博客了,默默的哀悼上個學期,本身瞎折騰,弄出的不成熟的東西。但願猴年是激情,奮鬥,收穫的一年~
ps:有沒有對我感興趣的boss收留~附交友地址一枚https://github.com/zrss
簡單粗暴的resume:https://github.com/zrss/ghostblog,近期再修改下