LeetCode每日一題 接雨水 動態規劃

2021-10-23 21:14:04 字數 2009 閱讀 8498

給定 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...