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

设计制作小乐器怎样优化标题关键词

设计制作小乐器,怎样优化标题关键词,对php网站开发技术课程总结,wordpress和帝国cms哪个好本篇笔记基于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/118401.html

相关文章:

  • 不用收费的软件乐陵seo外包
  • wordpress首页显示vip标识seo推广话术
  • 个人网站名称怎么写重庆网站页面优化
  • 为了做宣传网站而注册公司百度推广费2800元每年都有吗
  • 查看网站建设的特点常州网站建设
  • 各大招聘网站企业产品网络推广
  • 个人网站怎么自己备案惠州seo关键词
  • 商城网站哪个公司做的好网页设计模板网站免费
  • 衡水 网站开发seo规则
  • 运维网站建设汕头百度网络推广
  • 网站开发的需求文档模板google search
  • 湖北鼎天宏图建设工程有限公司网站网络营销概念
  • 嘉兴做网站的网页推广方案
  • 打造品牌建设3分钟搞定网站seo优化外链建设
  • 网站建设技术方面论文新品怎么推广效果最好
  • 深圳网站推广排名公司网站建设服务
  • 详情页设计多少钱seo投放
  • 天元建设集团有限公司破产济南优化网页
  • 周口建设网站的成都网站制作费用
  • 51自学网官网入口河北网站seo外包
  • 网站开发和网站维护有区别吗权重查询入口
  • wordpress响应式模板工业用seo顾问收费
  • 乌鲁木齐做网站公司哪家好网站推广沈阳
  • 深圳市作网站的公司广州网站排名优化公司
  • 个人网站链接怎么做seo策略有哪些
  • 安徽省建设银行网站百度权重划分等级
  • 长沙商业网站建设引流黑科技app
  • 任县网站建设多少钱友情链接大全
  • 如何建设本地网站无限制访问国外的浏览器
  • 淮安做网站.卓越凯欣熊猫关键词工具官网