有意思的數學題:Trapping Rain Water

來源:互聯網
上載者:User

標籤:

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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.