你是乙個專業的小偷,計畫偷竊沿街的房屋,每間房內都藏有一定的現金。這個地方所有的房屋都圍成一圈,這意味著第乙個房屋和最後乙個房屋是緊挨著的。同時,相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。
給定乙個代表每個房屋存放金額的非負整數陣列,計算你在不觸動警報裝置的情況下,能夠偷竊到的最高金額。
示例 1:
輸入: [2,3,2示例 2:]輸出:
3解釋: 你不能先偷竊
1 號房屋(金額 = 2),然後偷竊 3 號房屋(金額 = 2), 因為他們是相鄰的。
輸入: [1,2,3,1打家劫舍 ii 和 打家劫舍 相比,題目只有乙個變化。]輸出:
4解釋: 你可以先偷竊
1 號房屋(金額 = 1),然後偷竊 3 號房屋(金額 = 3
)。 偷竊到的最高金額 = 1 + 3 = 4 。
這個地方所有的房屋都圍成一圈,這意味著第乙個房屋和最後乙個房屋是緊挨著的。
這個規則會帶來怎樣的影響呢?
如果按照原來的解法,最要命的問題就是無法確定是否即搶了第一家又搶了最後一家。
那麼,要怎麼保證搶了第一家就不搶最後一家呢?
對於上面我們可以採取拆解的方式,變為兩個打家劫舍i的方式,如下:
相比於第一題,此題目將首位也作為相鄰,假設總共有n個房子,思路是:
1.分兩次求解,首先是第一家到第n-1家,求得偷得最多的值,記max01;
2.之後再次求得第2家到第n家可以偷的最大值,記為max02;
3.最後比較max01與max02,將最大的那個值返回。
對於上面的邏輯,用swift**如下:
import uikit通過playground列印出結果如下:let numsay: [int] = [2,7,9,3,1
]func robs(nums: [int]) ->int
if nums.count == 1
if nums.count == 2
else
}var dp1 =[int]()
var dp2: [int] = [0
] /**
*偷第一家與不偷第一家
*/var fk_1: int = 0
var fk_2: int = 0
//偷第一家
])
if dp1[0] < nums[1
] else
for i in
0..1
}//不偷第一家,可以偷最後一家
])
if dp2[1] < nums[2
] else
for i in
1..}
//比較大小
let maxrobs = dp1[dp1.count - 1] > dp2[dp2.count - 1] ? dp1[dp1.count - 1] : dp2[dp2.count - 1
]
return
maxrobs
}let maxrobs =robs(nums: numsay)
print(maxrobs)
直接拷貝上面**即可!
上面就是打家劫舍ii的版本,希望對大家理解有所幫助,看完麻煩點個贊唄,謝謝!
打家劫舍II
你是乙個專業的小偷,計畫偷竊沿街的房屋,每間房內都藏有一定的現金。這個地方所有的房屋都圍成一圈,這意味著第乙個房屋和最後乙個房屋是緊挨著的。同時,相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。給定乙個代表每個房屋存放金額的非負整數陣列,計算你在不觸動警報裝...
打家劫舍 II
相較於打家劫舍,算是乙個公升級版。既然是打家劫舍的公升級版,那我們就先找與原版之間的聯絡。做過打家劫舍之後我們知道狀態轉移方程是dp i max dp i 1 dp i 2 nums i 1 然後我們再來看這道題,由相鄰的一家變成了相鄰的兩家。那麼就相當於把原來的一條直線首尾相連變成了乙個環,這句話...
打家劫舍II
你是乙個專業的小偷,計畫偷竊沿街的房屋,每間房內都藏有一定的現金。這個地方所有的房屋都圍成一圈,這意味著第乙個房屋和最後乙個房屋是緊挨著的。同時,相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。給定乙個代表每個房屋存放金額的非負整數陣列,計算你在不觸動警報裝...