当前位置: 首页 > wzjs >正文

做海报找图片的网站郑州seo服务公司

做海报找图片的网站,郑州seo服务公司,成都企业模板建站,几十元做网站本篇笔记基于b站灵茶山艾府。 198. 打家劫舍 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统…

本篇笔记基于b站灵茶山艾府。

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 。

递归

我们可以 将大问题转换为规模更小的子问题

比如从第一个房子或者最后一个房子开始思考,下面从最后一个房子举例。

考虑最后一个房子是选还是不选

  • 如果不选,问题就变成前n-1个房子的问题
  • 如果选,问题就变成前n-2个房子的问题

从最后一个房子思考到第一个房子,就可以得到一棵二叉搜索树了:

在这里插入图片描述

当确定当前是选还是不选时,就确定下一次递归参数中的 i

dfs( i )的含义就是从前i个房子中得到的最大金额,如果不选当前第i个房子,问题就变成前i-1个房子的最大金额,也就是dfs( i - 1 ),如果选,问题就变成前i-2个房子的最大金额加上当前房子的金额,也就是dfs( i - 2 )+nums[i],同时,返回值就是前i个房子的最大金额。

class Solution:def rob(self, nums: List[int]) -> int:n = len(nums)def dfs(i):# 递到空节点了,返回0if i < 0:return 0return max(dfs(i - 1), dfs(i - 2) + nums[i])return dfs(n - 1)

也可以从第一个房子开始:

class Solution:def rob(self, nums: List[int]) -> int:n = len(nums)def dfs(i):if i >= n:return 0return max(dfs(i + 1), dfs(i + 2) + nums[i])return dfs(0)

运行结果:

在这里插入图片描述

由于时间复杂度是指数级别的,所以毫无疑问会超时

所以我们考虑不必要的重复计算,从而引出记忆化搜索


记忆化搜索

在计算dp[i]时,我们需要dp[i-1]与dp[i-2]的信息,而在计算dp[i-1]的信息时,由于已经用到了dp[i-2](因为计算dp[i-1]需要dp[i-2]与dp[i-3]的信息),所以dp[i-2]对于dp[i]来说已经 可以 是已知的了,所以不需要再次重复地计算dp[i-2],此时可以用一个memory数组来存储已经计算过的信息。

在这里插入图片描述

由于只有n个节点,时间复杂度也从指数级别降到了O( n )

对于python可以用cache装饰器:

cache 装饰器是 functools 模块中提供的一个工具,用于实现记忆化(Memoization)。它会自动缓存函数的返回值。当函数被多次调用时,如果输入参数相同,它会直接返回缓存的结果,而不会重新计算。

class Solution:def rob(self, nums: List[int]) -> int:from functools import cachen = len(nums)@cache	# 使用cache装饰器def dfs(i):# 递到空节点了,返回0if i < 0:return 0return max(dfs(i - 1), dfs(i - 2) + nums[i])return dfs(n - 1)

在这里插入图片描述

也可以自己实现:

class Solution:def rob(self, nums: List[int]) -> int:n = len(nums)cache = [-1] * n  # 答案不可能是负数def dfs(i):# 递到空节点了,返回0if i < 0:return 0# 如果记忆数组当前值不为-1,说明之前已经被赋值过,直接返回值,不需要重新计算if cache[i] != -1:return cache[i]res = max(dfs(i - 1), dfs(i - 2) + nums[i])cache[i] = resreturn resreturn dfs(n - 1)

在这里插入图片描述

从cache数组来看空间复杂度为O ( n ) ,有没有办法可以将空间复杂度优化到O(1)?

递推

在记忆化搜索中,我们从dfs( i )递到dfs( i - 1 )和dfs( i - 2 ),再从dfs( i - 1 )递到dfs( i - 2 )和dfs( i - 3 )…逐渐递到dfs( 0 ),再从dfs( 0 )直接归到dfs( i ),但是既然我们已经知道要从dfs(0)归到dfs( i ),不如 去掉递,直接归 ,直接从最下面开始计算,这就是递推。

将记忆化搜索改成递推很简单,只需要将dfs函数改成dp数组,递归的过程改成循环,递归的边界就用dp数组初始值代替。

class Solution:def rob(self, nums: List[int]) -> int:n = len(nums)if n == 1:return nums[0]dp = [0] * n  # 记录从下归到上的过程中的值dp[0] = nums[0]  # 初始化,对应dfs函数中判断边界的部分dp[1] = max(nums[0], nums[1])for i in range(2, n):dp[i] = max(dp[i - 1], dp[i - 2] + nums[i])  # 对应归的过程return dp[-1]

在这里插入图片描述

dp [ i ] 的含义就是前i个房子的最大价值

但是我们每次计算当前dp[i]的值,实际只需用到dp[i-1]与dp[i-2]的值,除此之外前面的值也是只用过一次就不要了,所以可以每次只维护三个值:dp[i]、dp[i-1]、dp[i-2],从而将空间复杂度降为 O(1)

class Solution:def rob(self, nums: List[int]) -> int:n = len(nums)if n == 1:return nums[0]i = nums[0]  # 对应dp[i-2]j = max(nums[0], nums[1])  # 对应dp[i-1]for x in range(2, n):k = max(i + nums[x], j)  # 对应dp[i]i = jj = kreturn k
http://www.dtcms.com/wzjs/487048.html

相关文章:

  • 镇江互联网公司宁波seo优化外包公司
  • 做传单的网站引擎优化搜索
  • 黄岛做网站锦绣大地seo
  • 俄罗斯b2b常用网站站长工具seo综合
  • 重庆涪陵网站建设公司国外免费网站域名服务器
  • 惠州网站建设制作优化电脑的软件有哪些
  • 冶金建设网站谷歌play商店官网
  • wordpress默认主题seo优化主要工作内容
  • 响应式网站 html素材网
  • 企业网站每年续费吗微平台推广
  • 垂直汽车网站做电商的优势巨量广告投放平台
  • 爱客crm手机下载seo零基础教学
  • 服装网站怎么做seo站长博客
  • php网站开发实用技术练习题app推广地推接单网
  • 弓长岭网站建设百度指数在线查询
  • 建站工具 比较邯郸网站优化公司
  • 昆明网络公司appseo百度关键词优化
  • 上海证券交易所网址东莞百度seo电话
  • 页优化软件杭州seo关键字优化
  • wordpress链接检查seo好找工作吗
  • html5结构的网站郑州推广优化公司
  • 免费做优化的网站竞价开户推广
  • 三河网站建设-七天网络杭州上城区抖音seo有多好
  • 牛商的网站后台黑龙江暴雪预警
  • 南京建设银行官方网站短视频如何引流与推广
  • 微网官方网站广告推广计划
  • 做网站的职位叫什么seo1搬到哪里去了
  • 选择网站开发公司的标准关键信息基础设施安全保护条例
  • 个人做动漫资源网站旺道网站优化
  • 啤酒网站建设百度推广怎么操作流程