算法(TS):打家劫舍

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。

示例 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 。

提示:

  • 1 <= nums.length <= 100
  • 0 <= nums[i] <= 400

解答

如果只有一个房间,则偷窃该房间能得到最大金额,如果只有两个房间,则偷金额最大的一个房间。由题可知不能偷连续两个房间,当房间数大于 2 时,有两个偷窃选项:

  1. 偷窃第 k 间房屋,那么就不能偷窃第 k−1 间房屋,偷窃总金额为前 k−2 间房屋的最高总金额与第 k 间房屋的金额之和。
  2. 不偷窃第 k 间房屋,偷窃总金额为前 k−1间房屋的最高总金额。

在两个选项中选择偷窃总金额较大的选项,该选项对应的偷窃总金额即为前 k 间房屋能偷窃到的最高总金额。假设 dp[k] 是前 k 个房间偷到的最大金额,则可以得到公式:dp[k] = max(dp[k-2] + nums[k], dp[k-1])

ini 复制代码
function rob(nums: number[]): number {
    if(nums.length === 0) return 0
  	if(nums.length === 1) return nums[0]
  
    const bp:number[] = []
    bp[0] = nums[0]
    bp[1] = Math.max(nums[0],nums[1])
    for(let i = 2; i < nums.length; i++) {
        bp[i] = Math.max(bp[i-2]+nums[i],bp[i-1])
    }

    return bp[nums.length-1]
};

考虑到每间房屋的最高总金额只和该房屋的前两间房屋的最高总金额相关,因此可以使用两个变量在每个时刻只需要存储前两间房屋的最高总金额。

ini 复制代码
function rob(nums: number[]): number {
    let f0 = 0
    let f1 = 0
    for(let i = 0; i < nums.length; i++) {
        [f0,f1] = [f1,Math.max(f0+nums[i],f1)]
    }

    return f1
};

时间复杂度O(n),空间复杂度O(1)

相关推荐
样例过了就是过了10 分钟前
LeetCode热题100 最大子数组和
数据结构·算法·leetcode
铸人19 分钟前
再论自然数全加和 - 欧拉伽马常数
数学·算法·数论·复数
m0_5312371742 分钟前
C语言-变量,枚举常量,字符串,打印类型,转义字符
c语言·数据结构·算法
zyeyeye1 小时前
自定义类型:结构体
c语言·开发语言·数据结构·c++·算法
俩娃妈教编程1 小时前
2023 年 03 月 二级真题(1)--画三角形
c++·算法·双层循环
niuniudengdeng1 小时前
一种基于高维物理张量与XRF实景复刻的一步闭式解工业级3D打印品生成模型
人工智能·python·数学·算法·3d
哈库纳玛塔塔1 小时前
公元前日期处理的两种方案
数据库·算法·mybatis
铸人2 小时前
再论自然数全加和 - 欧拉伽马常数6
算法
json{shen:"jing"}2 小时前
分割回文串-暴力法
java·算法
niuniudengdeng2 小时前
基于调度驱动与内存主动数据供给的非冯·诺依曼智能架构
算法