java动态规划解法_动态规划通用解法总结(示例代码)
背景:leetcode刷题遇到动态规划的题目,做不出来时看别人的code,也可以理解,但还是没有找到create solution的技巧,单纯的comprehend and remeber,直到遇到了下面这篇题解,终于形成了自己的动态规划通用解题方法,拿所有easy难度的题目试了下,结果横扫
https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/discuss/108870/Most-consistent-ways-of-dealing-with-the-series-of-stock-problems
在动态规划题目中,变形数量最多的差不多就是股票问题了,上述解法也围绕股票问题展开
根据上述帖子,我总结了动态规划的解题方法如下
Question1:如何识别题目适用于动态规划?
某一过程包含多种状态(情况),后一种状态的生成依赖于前面的情况
Quetion2:如何写动态规划?
1、找出问题中的状态(state)和选择(choice)
2、用选择去表达状态之间的转移
like below
for state1 instate1_list:for state2 instate2_list:for state3 instate3_list:
dp[state1][state2][state3]= choose(choice1, choice2, choice3)
其中所有的choice都用前面已计算出的状态来表示
Question3:如何优化动态规划?
在上述解题方案中,经常会有不必要的空间复杂度消耗,我们可以发现并通过适用常数个变量的方式替代适用数组或者矩阵。
Example:
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/house-robber
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
classSolution:"""步骤一:判断是否为动态规划题目;很明显,下一家的偷法依赖于前面的偷法,不同的偷法导致不同的偷盗总额,属于动态规划"""
def rob(self, nums: List[int]) ->int:if not nums or len(nums)==0:return0#步骤二:找到状态和选择;这里状态为当前偷到了第几家,用i表示,选择为偷或者不偷
dp ={}#初始化开始情况,当偷第-1家时,可以理解为偷得金额为0
dp[-1] =0
dp[0]=nums[0]#遍历的所有情况
for i in range(1,len(nums)):#这里的选择方法为取最大值,不同的选择分别代表偷与不偷
dp[i] = max(dp[i-2]+nums[i],dp[i-1])return dp[len(nums)-1]
步骤三:优化空间复杂度;上述解法用到了长为N的辅助列表,空间复杂度为O(n)。优化思路为用几个变量替代辅助列表
可以看到当前循环的dp[i],
依赖于当前循环dp[i-1]与dp[i-2],
即依赖于上一循环的dp[i]与dp[i-1],
所以我们用2个变量即可解决该问题,分别cur与pre即可
代码可优化为
classSolution:def rob(self, nums: List[int]) ->int:if not nums or len(nums)==0:return0
pre=0
cur=nums[0]for i in range(1,len(nums)):
tmp=cur
cur= max(pre+nums[i],cur)
pre=tmpreturn cur
另外,讲一下python实现动态规划过程中需要注意的一点,
与java不同,java可以直接int[][]初始化多重数组并赋予默认值,然后直接用索引取访问对应元素即可,但python的list结构不会初始化大小,需要我们自己初始化,否则直接使用索引会索引越界
如
#初始化长度为10的一维数组并赋予默认值0
dp = [0]*10
#初始化10*3的二维数组并赋予默认值0
dp = [[0]*10 for _ in range(10)]
但问题是,某些情况下需要我们去思考默认值赋予什么才比较合适,这样会造成困扰,我们更希望不用去思考初始化为何值(keep None即可),如下
#初始化字典(哈希表)代替一维数组(list)
dp ={}#初始化10个字典并放到一维数组中
dp = [{} for _ in range(10)]
这样就解决了不给出默认值用于内存分配导致的角标越界问题
归纳出上述套路之后,leetcode遇到动态规划的题目再也不会毫无头绪啦~~~
java动态规划解法_动态规划通用解法总结(示例代码)相关推荐
- java话费清单_查询话费订单列表示例代码
package api.binstd.mobilerecharge; /** * 查询话费订单列表 */ import api.util.HttpUtil; import net.sf.json.JS ...
- java话费清单_查询话费订单详情示例代码
package api.binstd.mobilerecharge; /** * 查询话费订单详情 */ import api.util.HttpUtil; import net.sf.json.JS ...
- Java Singleton类中的线程安全性的示例代码
Java Singleton类中的线程安全性的示例代码 Singleton是最广泛使用的创建设计模式之一,用于限制应用程序创建对象.在实际应用程序中,数据库连接或企业信息系统(EIS)等资源是有限的, ...
- 纯java pdf转换成html,JAVA实现PDF转HTML文档的示例代码
本文是基于PDF文档转PNG图片,然后进行图片拼接,拼接后的图片转为base64字符串,然后拼接html文档写入html文件实现PDF文档转HTML文档. 引入Maven依赖 org.apache.p ...
- java 静态数据_Java 静态数据初始化的示例代码
无论创建多少个对象,静态数据都只占用一份存储区域.static关键字不能应用于局部变量,因此它只能作用于域.如果一个域是静态的基本类型域,且也没有对它进行初始化,那么它就会获得基本类型的标准初始值:如 ...
- java通过单号判断快递公司的示例代码
通过单号判断快递公司的示例代码有很多种,以下是快递100Java智能单号判断功能接入. 不过首先要拿到快递100的测试账号和密钥,获取方式只需要去官网注册后,登录后台进入用户信息模块就能看到了. ht ...
- java动态规划 硬币_动态规划-硬币问题
算法思想:动态规划 实际问题:硬币问题 编写语言:Java 问题描述 假设有 1 元,3 元,5 元的硬币若干(无限),现在需要凑出 n 元.问如何组合才能使硬币的数量最少? 关键特征 要推出问题的关 ...
- java动态规划算阶乘_动态规划算法
上世纪40年代,RichardBellman最早使用动态规划这一概念表述通过遍历寻找最优决策解问题的求解过程.1953年,RichardBellman将动态规划赋予现代意义,该领域被IEEE纳入系统分 ...
- python动态规划图解_动态规划案例之python实现(一)
假设你正在爬楼梯.需要 n 阶你才能到达楼顶. 每次你可以爬 1 或 2 个台阶.你有多少种不同的方法可以爬到楼顶呢? 注意:给定 n 是一个正整数. 示例 1: 输入: 2 输出: 2 解释: 有两 ...
最新文章
- 分析函数调用的汇编指令
- 《剑指offer》— JavaScript(24)二叉树中和为某一值的路径
- 微信朋友圈+html+字体,一键修改微信朋友圈字体,快来试试吧
- Maven解决jar包版本冲突
- 48个越吃越瘦的诀窍 - 生活至上,美容至尚!
- 【Java】关键词strictfp解析
- 10个简单步骤,完全理解SQL
- 陕西师范大学计算机学院范虹,周素芳 -计算机与信息工程学院官网
- scala编程_Scala编程语言简介
- 【181220】VC++ 简易的人工智能模型源程序源代码
- gns3gns3下载_如何将Gns3安装到Fedora?
- C语言题库 part.1
- matlab gui双音拨号,用matlab GUI功能模拟DTMF拨号系统.doc
- win8系统计算机属性在哪个文件夹,Win8如何更改文件夹的只读或系统属性
- cuteftp不能连接虚拟机的解决方法
- theta悖论:4-8 Hz的EEG振荡既反映睡眠压力又体现认知控制
- 简评几款开源RISC-V处理器
- 英语----非谓语的另类运用:独立主格
- 涂鸦智能校招——前端
- EXCEL生成随机密码函数