這次準備連講三道題,這道題就是最基礎的,利用動態規劃可以解決。
你是乙個專業的小偷,計畫偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。
給定乙個代表每個房屋存放金額的非負整數陣列,計算你在不觸動警報裝置的情況下,能夠偷竊到的最高金額。
示例 :
輸入: [1,2,3,1]
輸出: 4
解釋: 偷竊 1 號房屋 (金額 = 1) ,然後偷竊 3 號房屋 (金額 = 3)。
偷竊到的最高金額 = 1 3 = 4 。
原題url:
小偷到了第3家,他有兩個選擇:不偷第3家之後去第4家、偷完第3家之後去第5家。這時他需要比較的是:
那主要目的就是要求出從當前到結尾可以偷到的最大值,為了不重複計算,可以利用乙個陣列記錄中間結果。
接下來看看**:
class solution
// 儲存中間結果
int result = new int[nums.length];
arrays.fill(result, -1);
// 動態規劃,利用中間結果,尋找最大值
dp(0, nums, result);
return result[0];
}public int dp(int start, int nums, int result)
if (result[start] != -1)
result[start] = math.max(
// 選擇偷當前的家
nums[start] dp(start 2, nums, result),
// 選擇不偷當前的家
dp(start 1, nums, result)
);return result[start];}}
提交ok。
上面的寫法其實是從頭向尾考慮,寫法上是遞迴。那麼如果想不用遞迴呢?畢竟遞迴也是有缺陷的,如果次數過多,總呼叫棧就會很長。那我們來改造一下。
如果我們是從尾向頭考慮呢?也就是從最後一家開始,選擇偷或者不偷,最終到第一家。思想上還是很好理解的,和上面差不多,讓我們看看**:
class solution
// 儲存中間結果
int result = new int[nums.length 2];
// 動態規劃,利用中間結果,尋找最大值
for (int i = nums.length - 1; i >= 0; i--)
return result[0];}}
提交也是ok的。
我們仔細觀察一下上面的寫法,其實每次你利用到的中間狀態只有兩個,下乙個位置和再下乙個位置。那麼此時我們也可以用三個變數來儲存就夠了,兩個儲存之後的值,還有乙個儲存當前的值。
讓我們來看看**:
class solution
// 儲存當前位置,下乙個位置,和再下乙個位置的結果
int current = 0;
int next_1 = 0;
int next_2 = 0;
// 動態規劃,利用中間結果,尋找最大值
for (int i = nums.length - 1; i >= 0; i--)
return current;}}
以上就是這道題目我的解答過程了,不知道大家是否理解了。這道題主要利用動態規劃就可以解決,可以改寫遞迴,優化空間複雜度。
力扣 198 打家劫舍
題目 你是乙個專業的小偷,計畫偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。給定乙個代表每個房屋存放金額的非負整數陣列,計算你在不觸動警報裝置的情況下,能夠偷竊到的最高金額。示例 1 輸...
力扣 198 打家劫舍
題目描述 你是乙個專業的小偷,計畫偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。給定乙個代表每個房屋存放金額的非負整數陣列,計算你 不觸動警報裝置的情況下 一夜之內能夠偷竊到的最高金額。...
力扣198 打家劫舍
這次準備連講三道題,這道題就是最基礎的,利用動態規劃可以解決。你是乙個專業的小偷,計畫偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。給定乙個代表每個房屋存放金額的非負整數陣列,計算你在不...