經典dp--搶家奪舍系列之GO寫法
搶家奪舍系列–經典dp系列GO寫法
house-robber
首先我們從比較簡單的角度來做:
- 判斷狀態:題目只有兩種狀態,也就是偷或者不偷,所以我們可以建立一個二維的陣列,並用0表示不偷,1表示偷
- 陣列的長度:這個實際上就是你房子的數量;
- 狀態轉移方程:當你在第i家時,選擇不偷時,dp[i][0]就是選擇dp[i-1]中最大的一個,選擇偷的話,前面那家肯定不能偷,因此dp[i][1] = nums[i] + dp[i-1][0]。所以有狀態轉移方程:
- 最後Max(dp[len - 1][0], dp[len - 1][1])就是結果啦
// accept code 程式碼一
func rob(nums []int) int {
length := len(nums)
if length < 1 {
return 0
}
dp := make([][2]int, length)
dp[0][1] = nums[0]
dp[0][0] = 0
for i := 1; i < length; i++ {
dp[i][0] = max(dp[i-1][0], dp[i-1][1])
dp[i][1] = dp[i-1][0] + nums[i]
}
return max(dp[length-1][0], dp[length-1][1])
}
func max(values ...int) int {
maxValue := math.MinInt32
for _, value := range values {
if value > maxValue {
maxValue = value;
}
}
return maxValue;
}
值得注意的是,這個程式碼可以簡化成一維陣列,dp[i]表示當前i房子後能偷到的最多錢,所以我們可以利用i i-1 and i-2 來表示鄰避關係,也就是說有狀態轉移方程:
//程式碼二
func rob(nums []int) int {
length := len(nums)
if length < 1 {
return 0
}
if length == 1 {
return nums[0];
}
dp := make([]int, length)
dp[0] = nums[0]
dp[1] = nums[1]
for i := 2; i < length; i++ {
dp[i] = max(dp[i-2]+nums[i], dp[i-1])
}
return dp[length-1]
}
func max(values ...int) int {
maxValue := math.MinInt32
for _, value := range values {
if value > maxValue {
maxValue = value;
}
}
return maxValue;
}
通過程式碼二我們可以進一步優化空間複雜度,因為我們可見不論怎樣,dp狀態轉移方程只跟
i i-1 and i-2 這三者有關,所以我們可以只使用三個變數dp, dp1, dp2來進行更新:
dp1 = dp2
dp2 = dp
因此有程式碼:
//程式碼三
func rob(nums []int) int {
length := len(nums)
if length < 1 {
return 0
}
dp1 := 0 //初始化為0 邊界需要判斷清晰
dp2 := 0
dp := 0
for i := 0; i < length; i++ {
dp = max(dp1 + nums[i], dp2)
dp1 = dp2
dp2 = dp
}
return dp
}
func max(values ...int) int {
maxValue := math.MinInt32
for _, value := range values {
if value > maxValue {
maxValue = value;
}
}
return maxValue;
}
house-robber-II
這個題目有限制就是陣列是為一個環形陣列,因此我們可以分為兩種情況考慮,當選第一個來偷時,就不再考慮最後一個房子;當選最後一個來偷時,就不再考慮第一個房子;最後對於這兩種情況選出一個最大值出來就好啦。
所以改改上面的程式碼就好了:
func rob(nums []int) int {
length := len(nums)
if length < 1 {
return 0;
} else if length == 1 {
return nums[0];
}
return max(subRob(nums,0, length - 2), subRob(nums, 1, length - 1))
}
func subRob(nums []int, st, ed int) int {
dp := 0
dp1 := 0
dp2 := 0
for i := st; i <= ed; i++ {
dp = max(dp1 + nums[i], dp2)
dp1 = dp2
dp2 = dp
}
return dp
}
func max(a, b int) int {
if a < b {
return b
}
return a
}
house-robber-III
這個是採用樹的形式,同理,對於某一個節點我們可偷可不偷,我們儲存兩個狀態,rob and noRob。 所以有計算公式:
func rob(root *TreeNode) int {
if root == nil {
return 0
}
noRob, rob := getResult(root);
return Max(noRob, rob);
}
func getResult(root *TreeNode) (a, b int) {
if root == nil{
return 0, 0
}
left0, left1 := getResult(root.Left)
right0, right1 := getResult(root.Right)
rob := root.Val + left0 + right0
// 可偷子節點或者不偷子節點,選最大的那個情況就好
noRob := Max(left0, left1) + Max(right0, right1)
return noRob, rob
}
func getResult(root *TreeNode) (noRob, rob int) {
if root == nil{
return 0, 0
}
left0, left1 := getResult(root.Left)
right0, right1 := getResult(root.Right)
rob = root.Val + left0 + right0
noRob = Max(left0, left1) + Max(right0, right1)
return
}
func Max(a,b int) int {
if a < b {
return b
} else {
return a
}
}
相關文章
- 經典演算法之回溯法演算法
- Oracle RAC系列之:ASM基本操作維護(經典)OracleASM
- 《Win7正當年》系列之經典“介面元素”Win7
- Go語言經典筆試題Go筆試
- Go系列之反射Go反射
- arping強制搶奪ip
- 白話經典演算法系列之七 堆與堆排序演算法排序
- Go語言入門經典第18章Go
- 微軟經典面試100題系列(部分)微軟面試
- OpenCV之C++經典案例OpenCVC++
- 奪命雷公狗-----React---24--小案例之react經典案例todos(單條任務的刪除)React
- 白話經典演算法系列之六 快速排序 快速搞定 【轉】演算法排序
- 清華尹成帶你實戰GO案例(42)Go 經典hello worldGo
- 67.Java-資源搶奪案例(使用synchronized)Javasynchronized
- 機器學習經典演算法之EM機器學習演算法
- 機器學習經典演算法之KNN機器學習演算法KNN
- 經典排序之選擇排序(Java)排序Java
- 經典演算法之快速排序演算法排序
- css經典佈局系列一——垂直居中佈局CSS
- 迴文數系列題目(經典演算法)演算法
- Go語言庫系列之emailGoAI
- 經典演算法研究系列:九、影象特徵提取與匹配之SIFT演算法演算法特徵
- JavaScript設計模式經典之代理模式JavaScript設計模式
- 《Flutter 入門經典》之“Flutter 入門 ”Flutter
- jquery經典例項之回到頂部jQuery
- JavaScript設計模式經典之策略模式JavaScript設計模式
- Go編譯原理系列3(詞法分析)Go編譯原理詞法分析
- Go編譯原理系列4(語法分析)Go編譯原理語法分析
- 研究顯示移民並未搶奪美國人的工作
- css經典佈局系列二——等分等高佈局CSS
- jQuery/CSS3經典按鈕系列外掛(一)jQueryCSSS3
- 騰訊前端一面經典手寫面試題合集前端面試題
- 機器學習經典演算法之決策樹機器學習演算法
- 經典演算法之折半插入排序演算法排序
- CSS經典佈局之Sticky footer佈局CSS
- 翻譯經典之《Cisco Lan Switching》:前言
- JavaScript設計模式經典之觀察者模式JavaScript設計模式
- JavaScript設計模式經典之單例模式JavaScript設計模式單例