题目描述
给定一个数组,表示房屋中的每个房间里的钱。你不能同时抢劫相邻的房屋,否则会触发警报。计算能够抢劫到的最大数量。
示例
示例1:
Input: [1,2,3,1]
Output: 4
Explanation: 抢劫第1个房间(金额为1),然后抢劫第3个房间(金额为3)。总共的收益为1+3=4。
示例2:
Input: [2,7,9,3,1]
Output: 12
Explanation: 抢劫第1个房间(金额为2),然后抢劫第3个房间(金额为9),最后抢劫第5个房间(金额为1)。总共的收益为2+9+1=12。
解法
这道题可以使用动态规划来解决,我们可以定义dp[i]表示抢劫前i个房间所能获得的最大利润。那么对于第i个房间,我们只有两种选择:
- 不抢这个房间,那么当前最大利润就是前(i-1)个房间所能获得的最大利润,即dp[i-1];
- 抢这个房间,那么当前最大利润就是前(i-2)个房间所能获得的最大利润加上当前房间中的钱数,即dp[i-2]+nums[i-1]。
因此,我们可以得到状态转移方程:dp[i] = max(dp[i-1], dp[i-2]+nums[i-1])。最终的答案就是dp[n],其中n为数组的长度。
代码
function rob(nums: number[]): number {
const n = nums.length;
if (n === 0) return 0;
let dp: number[] = new Array(n + 1).fill(0);
dp[1] = nums[0];
for (let i = 2; i <= n; i++) {
dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i - 1]);
}
return dp[n];
}
时间复杂度
遍历整个数组需要花费的时间,对于每个位置,我们只需要进行常数级别的操作,因此总的时间复杂度为。