給定 n 個非負整數表示每個寬度為 1 的柱子的高度圖,計算按此排列的柱子,下雨之後能接多少雨水。
如圖:
這道題的解法依舊很簡單,我們可以搜尋兩個相同數列,取他的指標相加減,也可以從底部向上依次累加,尋找每一層會存續的水,我們依舊先看暴力解法是否可以完成。
在暴力解法之中,我們可以一層一層的搜尋,將每一層可能蓄積的水都做出來,直到最高的的水位,原理較為簡單,具體注釋在**中表明,時間複雜度為 o(n2),我們可以稍微簡化一下,讓第二次遍歷不需要遍歷全部列表,具體**如下:
func
trap
(arr [
]int
)int
for k :=
1;k<=
maxheight
(arr)
;k++}}
return unit
}//找到最高的柱子
func
maxheight
(arr [
]int
)int
}return maxval
}//找到最開始的能承接水位的位置
func
min(arr [
]int
,aa int
)int
}return index
}//找到最後能承接水的位置
func
max(arr [
]int
,aa int
)int
}return index
}
我們看之前的暴力解法,是否可以簡化,事實上,原來的暴力演算法在每一次提公升的時候,都要遍歷一遍陣列,找到左右兩邊的水位值,能否對此進行優化,就是下一步演算法要做的事情,做動態規劃的前提,就是先了解暴力演算法如何解,如果能用動態規劃將所有水位記錄下來,然後將這個水位與當前位置進行比對,就能得出此處是否有積水,積水多少,遍歷一次即可結束。
由於對於每處的最高水位要看左右兩個最高的水柱,所以我們可以左右各經歷一次遍歷,取其水位較小值和當然位置進行對比,具體演算法模型如圖推導:
假設有如圖的水柱:
我們先從左到右按照最高水位來計量:
然後按照從右到左的方向,以同樣方式計量:
然後在遍歷時取到他們的最小值,兩相結合就可以得到他們的最高水位:
具體**如下:
func
trap
(height [
]int
)int
size :=
len(height)
res :=
0 leftdp :=
make([
]int
,size)
rightdp :=
make([
]int
,size)
leftdp[0]
= height[0]
rightdp[size-1]
= height[size-1]
for i:=
1;ifor i:=size-
2;i>=
0;i--
for i:=
1;i1;i++
return res
}func
max(a,b int
)int
return b
}func
min(a,b int
)int
return a
}
LeetCode刷題 接雨水
給定 n 個非負整數表示每個寬度為 1 的柱子的高度圖,計算按此排列的柱子,下雨之後能接多少雨水。上面是由陣列 0,1,0,2,1,0,1,3,2,1,2,1 表示的高度圖,在這種情況下,可以接 6 個單位的雨水 藍色部分表示雨水 時間複雜度o n 空間複雜度o n int trap vector ...
每日一題 LeetCode
在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數。示例 1 輸入 7,5,6,4 輸出 5 限制 0 陣列長度 50000 思想是 分治演算法 所有的 逆序對 於 3 個部分 左邊區間的逆序對 右邊區間的逆序對 橫跨兩個區間的...
leetcode題 42 接雨水(困難)
給定 n 個非負整數表示每個寬度為 1 的柱子的高度圖,計算按此排列的柱子,下雨之後能接多少雨水。上面是由陣列 0,1,0,2,1,0,1,3,2,1,2,1 表示的高度圖,在這種情況下,可以接 6 個單位的雨水 藍色部分表示雨水 感謝 marcos 貢獻此圖。示例 輸入 0,1,0,2,1,0,1...