左神(講題者)上來就先排除了找波谷的做法,因為這種想法雖然可行,但是會把問題引向複雜處(我原來就是類似這種做法),不是好辦法。
他給出了這樣一種思路:我們只要知道每乙個長方形上面有多少水,那麼求和就能知道所有的水有多少了
我們怎麼知道某長方形上有多少水呢?
如果乙個長方形的左側,沒有其他長方形比他高了,那麼這個長方形是一定放不了水的,因為會從左側流出。
同理,右側也必須有比他高的長方形才可以。
如此,我們便知道了哪種長方形是可以放水的,即左右側都存在比他高的長方形,即ledt_max > self && right_max > self
;
那麼滿足條件的長方形能放多少水呢?
這個很顯然,能放多少水由左右側兩個最大值中的較小值決定,即能放min - self
數量的水。
至此,我們已經能寫出**了。
如果按照上面的辦法寫**,時間複雜度是o(n^2)。這是要扣分的。
主要就是在找最大值的時候得遍歷左右側。其實每個位置的左右側最大值都是固定的,所以我們一開始就用兩個陣列存好這些最大值即可。
這樣我們就不用迴圈裡面套迴圈了。
時間複雜度降為o(n)。
這裡其實是最秀的,上面時間優化後的做法的空間複雜度為o(n),其實可以降為o(1).
用左右兩個指標l、r向中間移動。
用兩個變數left_max、right_max分別記錄指標左右側的最大值。
如果出現左(右)最大值小於等於左(右)指標所指的值,顯然是裝不了水了,移動指標。
left_max > height[l] && right_max > height[r]
時,判斷左右兩個最大值的大小,若left_max < right_max
,我們就知道,左指標指向的長方形的水是可以確定了的,計算水量,移動l,更新left_max
;若left_max > right_max
,我們就知道,右指標指向的長方形的水是可以確定了的,計算水量,更新r,更新right_max
;
秀
impl solution
let mut sum = 0;
let mut l = 1;
let mut r = height.len() - 2;
let mut left_max = height[0];
let mut right_max = height[r+1];
while l <= r else ;
l += 1;
continue;
}if right_max <= height[r] else ;
r -= 1;
continue;
}if left_max < right_max else if left_max > right_max else
} sum
}}
Leetcode 42 接雨水(棧解)
題目描述 定 n 個非負整數表示每個寬度為 1 的柱子的高度圖,計算按此排列的柱子,下雨之後能接多少雨水。上面是由陣列 0,1,0,2,1,0,1,3,2,1,2,1 表示的高度圖,在這種情況下,可以接 6 個單位的雨水 藍色部分表示雨水 示例 輸入 0,1,0,2,1,0,1,3,2,1,2,1 ...
力扣接雨水問題
思路是這樣的,先找到陣列中的最大值,然後在以他為中心,左右分割遍歷陣列,遞迴陣列,總是找最大值,計算 兩個最大值之間的存水量 最後彙總相加即可得出結果.package test public class testcasetwo int reuslt trapleft height,maxinx tr...
演算法練習 接雨水問題
給定 n 個非負整數表示每個寬度為 1 的柱子的高度圖,計算按此排列的柱子,下雨之後能接多少雨水。示例 輸入 0,1,0,2,1,0,1,3,2,1,2,1 輸出 6 先找出最高的柱子,然後從兩邊向其遍歷,如果後乙個高度比前乙個柱子高度低,則可以存水,存水量是兩根柱子的差值 public stati...