LeetCode——198.打家劫舍
題目
198.打家劫舍
你是一個專業的小偷,計劃偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。
給定一個代表每個房屋存放金額的非負整數數組,計算你 不觸動警報裝置的情況下 ,一夜之內能夠偷竊到的最高金額。
示例 1:
輸入: [1,2,3,1]
輸出: 4
解釋: 偷竊 1 號房屋 (金額 = 1) ,然後偷竊 3 號房屋 (金額 = 3)。
偷竊到的最高金額 = 1 + 3 = 4 。
示例 2:
輸入: [2,7,9,3,1]
輸出: 12
解釋: 偷竊 1 號房屋 (金額 = 2), 偷竊 3 號房屋 (金額 = 9),接着偷竊 5 號房屋 (金額 = 1)。
偷竊到的最高金額 = 2 + 9 + 1 = 12 。
解析
動態規劃,公式推導如下
圖片來自LeetCode視頻題解
代碼
動態規劃
//動態規劃
class Solution {
public int rob(int[] nums) {
int n = nums.length;
if (n==0){ //沒有房屋
return 0;
}
if (n==1){ //只有一個房屋
return nums[0];
}
//多間房屋
int[] s = new int[n];
s[0] = nums[0]; //狀態1初始化爲第一間房的錢數
s[1] = Math.max(nums[0], nums[1]); //狀態2初始化爲第一間房和第二間房中錢數較大的那個
for (int i = 2; i < n; i++) {
s[i] = Math.max(s[i-1],s[i-2] + nums[i]); //公式
}
return s[n-1];
}
}
動態規劃+滾動數組(優化空間複雜度)
//動態規劃+滾動數組(優化空間)
class Solution {
public int rob(int[] nums) {
int n = nums.length;
if (n==0){ //沒有房屋
return 0;
}
if (n==1){ //只有一個房屋
return nums[0];
}
//多間房屋
int first = nums[0]; //狀態1初始化爲第一間房的錢數
int second = Math.max(nums[0], nums[1]); //狀態2初始化爲第一間房和第二間房中錢數較大的那個
for (int i = 2; i < n; i++) {
int temp = second; //設置一個臨時變量存放第二個狀態
second = Math.max(first+nums[i],second);//公式
first = temp; //更新第一個狀態
}
return second;
}
}