標籤:
LeetCode傳送門 https://leetcode.com/problems/trapping-rain-water/
目標:找出積木能容納的水的“面積”,中黑色部分是積木,藍色為可容納水的部分
假設:積木寬度均為1
輸入:各個積木的高度
輸出:所有積木能容納水的“面積”
思考過程
1. 逐一求積木的間隔似乎不太容易。特別對於圖中3-7積木間的容積,如果可以先求底部(4-6間)的容積,當求解上層(3-7)的容積時,還需要做額外的處理,如減掉底部的高度。
2. 既然如此,可否先求出3-7間整體的容積,再將兩積木之間的積木面積(4、5、6)減去,即可得這個地區的容積?
3. 那麼問題轉換成了,已知一個積木,如何尋找下一個積木,並計算這個兩積木間的容積
4. 嘗試一,尋找一個至少不比當前積木低的積木,作為下一個積木,例子為當前積木3,下一個積木7。那麼之間的容積如何計算呢,簡單,積木3的高度乘以兩積木間的間隔寬度,再減去,積木3與積木7之間的積木(4、5、6)面積。
5. 問題:下次迭代從何開始?上一個例子,可以從積木7繼續算起。然而如果找不到相應的積木呢,那麼從積木3的下一個積木4開始。
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的bar18 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 // 尋找更高的或相等的bar31 // 同時記錄遍曆過的最高的bar32 // 如果尋找不到更高的或相等的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 }Trapping Rain Water
閑聊一二
大年初一!祝大家猴年快樂啦,已經工作的童鞋升職加薪,要實習、找工作的童鞋offer多多~博主今年也要面對找實習、找工作的人生大事兒了。好久沒寫部落格了,默默的哀悼上個學期,自己瞎折騰,弄出的不成熟的東西。希望猴年是激情,奮鬥,收穫的一年~
ps:有沒有對我感興趣的boss收留~附交友地址一枚https://github.com/zrss
簡單粗暴的resume:https://github.com/zrss/ghostblog,近期再修改下
有意思的數學題:Trapping Rain Water