題面
給出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]表示。在這種情況下,6個單位的雨水(藍色部分)被儲存。
輸入
[0,1,0,2,1,0,1,3,2,1,2,1]
輸出
6
分析
- 關鍵 構建V型雨水收集器區間 即左右邊界及坑底
- 確保入棧索引對應的高程資料比棧頂小,即為單調遞減棧
- 反之出棧,前一棧頂視為坑,出棧後的棧頂視為左邊界,當前索引位為右邊界
- 計算雨水量,長為當前索引位與當前棧頂位之差,高為兩邊界之最小峰值與前坑高程之差
上碼
func trap( A []int ) int {
var rs int
for i,st :=0,[]int{};i<len(A);{
if len(st)==0 || A[i]<= A[st[len(st)-1]]{
st = append(st,i)
i++
}else{
// 將出棧位視為坑
prev := st[len(st)-1]
st = st[:len(st)-1]
if len(st)>0 {
rs += (i - st[len(st)-1] -1)*( minH(A[i], A[st[len(st)-1]]) - A[prev])
}
}
}
return rs
}
func minH(a,b int)int {
if a < b {
return a
}
return b
}
小結
- V型序列資料,大–小–大, 出棧實現頂與底部轉化
- 入棧單調遞減,否則二選一,出入棧時機,雨水可收集可計算條件
本作品採用《CC 協議》,轉載必須註明作者和本文連結