算法(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)

相关推荐
春日见3 小时前
丝滑快速拓展随机树 S-RRT(Smoothly RRT)算法核心原理与完整流程
人工智能·算法·机器学习·路径规划算法·s-rrt
Code小翊3 小时前
”回调“高级
算法·青少年编程
云里雾里!3 小时前
力扣 977. 有序数组的平方:双指针法的优雅解法
算法·leetcode·职场和发展
一只侯子6 小时前
Face AE Tuning
图像处理·笔记·学习·算法·计算机视觉
jianqiang.xue6 小时前
别把 Scratch 当 “动画玩具”!图形化编程是算法思维的最佳启蒙
人工智能·算法·青少年编程·机器人·少儿编程
不许哈哈哈7 小时前
Python数据结构
数据结构·算法·排序算法
J***79397 小时前
后端在分布式系统中的数据分片
算法·哈希算法
sin_hielo9 小时前
leetcode 2872
数据结构·算法·leetcode
dragoooon349 小时前
[优选算法专题八.分治-归并 ——NO.49 翻转对]
算法
u***27619 小时前
TypeScript 与后端开发Node.js
javascript·typescript·node.js