198.打家劫舍
题目
LeetCode 中等
INFO
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
示例:
输入:[1,2,3,1]
输出:4
解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
偷窃到的最高金额 = 1 + 3 = 4 。
输入:[2,7,9,3,1]
输出:12
解释:偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
偷窃到的最高金额 = 2 + 9 + 1 = 12 。
题解
方法:空间复杂度 O(n)
DP
O(n) O(n)
ts
function rob(nums: number[]): number {
const len = nums.length
if (len === 1) return nums[0]
const dp = [nums[0], Math.max(nums[0], nums[1])]
for (let i = 2; i < len; i++) {
dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]) //当前家 偷 或 不偷
console.log(i, '-', dp[i - 1], dp[i - 2] + nums[i])
}
console.log(dp)
return dp[len - 1]
}
const nums = [2, 7, 9, 3, 1]
console.log('🌰', rob(nums))
方法:空间复杂度 O(1)
DP
O(n) O(1)
ts
function rob2(nums: number[]): number {
const len = nums.length
if (len === 1) return nums[0]
let p2 = nums[0] //前面第二个
let p1 = Math.max(nums[0], nums[1]) //前面一个
let res = p1
for (let i = 2; i < len; i++) {
res = Math.max(p1, p2 + nums[i]) //当前家 偷 或 不偷
p2 = p1
p1 = res
console.log('i', i, 'p2', p2, 'p1', p1, 'res', res)
}
return res
}
console.log('🌰', rob2(nums))