又到了晚上,动态规划,开刷!

第121题 Best Time to Buy and Sell Stock

题目的意思:给予一个数组price,表示特定股票在某天的股价,里面第i个数表示第i天的价格。只能交易一次(买一次+卖一次),求最大利润

分析:典型的动态规划。当我们要求到第i天为止最大的利润,就需要知道i-1天为止的最大利润,然后用第i天的股价减去(i-1)天股票最低值,然后比较即可。所以我们可以推出状态转移方程:

  1. maxProfit(i) = max(maxProfit(i-1), price[i] - min(price[:i]))

下面是代码:

  1. class Solution:
  2. # @param {integer[]} prices
  3. # @return {integer}
  4. def maxProfit(self, price):
  5. maxprofit = 0
  6. nextprofit = 0
  7. profit = 0
  8. if len(price) <= 1:
  9. return 0
  10. for i in range(1, len(price)):
  11. nextprofit = max(profit, price[i] - min(price[:i]))
  12. maxprofit = max(maxprofit, nextprofit)
  13. profit = nextprofit
  14. return maxprofit

可是这样提交上去,返回了一个运行超时..(未通过) 但是大体思路是正确的,所以我就想对这个程序进行改进。我注意到这几个min,max函数上。要知道,虽然我们使用了这个python提供的函数,但是python的实现过程肯定不是O(1),肯定内部实现是需要排序的,这里就和我的遍历重复了! 所以我在for循环外添加了一个变量minNumminNum = price[0]用来记录最小值,然后在for循环中进行了如下修改:

  1. for i in range(1, len(price)):
  2. if price[i] < minNum:
  3. minNum = price[i]
  4. else:
  5. nextprofit = max(profit, price[i] - minNum)
  6. maxprofit = max(maxprofit, nextprofit)
  7. profit = nextprofit

第53题 Maximum Subarray

题目的意思:求和为最大的子串,例如数组[−2,1,−3,4,−1,2,1,−5,4],它的最大子串为[4,−1,2,1],和为6

分析:如果当前和为负数,后面的数值加上当前和则必然小于原数值,则应将当前和丢弃

  1. class Solution:
  2. # @param {integer[]} nums
  3. # @return {integer}
  4. def maxSubArray(self, nums):
  5. cursum = 0
  6. maxsum = -2147483648
  7. for i in range(len(nums)):
  8. if cursum <= 0:
  9. cursum = nums[i]
  10. else:
  11. cursum += nums[i]
  12. maxsum = max(maxsum, cursum)
  13. return maxsum

该题的变种:给一个数组,求这个数组中子序列和最大的最短子序列

比如数组a[]={1,2,2,-3,-5,5}子序列和最大为5,最短的为a[5]

分析:首先,我们可以用上面的方法求出和最大的序列和,但是这里我们可以使用一个字典来储存这个子序列。当遇到两个子序列和一样的时候,比较子序列长度,取长度小的那个。下面是代码:

  1. def maxSum(li):
  2. cursum = 0
  3. maxsum = -2147483648
  4. templist = [] #增加一个临时列表变量,用于记录子序列
  5. shortDict = dict()
  6. for i in range(len(li)):
  7. if cursum > 0:
  8. cursum += li[i]
  9. templist.append(li[i]) #把该元素推入列表中
  10. else:
  11. cursum = li[i]
  12. templist[:] = [] #此时cursum<=0,不符合条件,所以清空列表
  13. templist.append(li[i]) #把该元素推入数组中
  14. if maxsum > cursum:
  15. pass
  16. if maxsum < cursum:
  17. maxsum = cursum
  18. shortDict[maxsum] = templist[:]
  19. if maxsum == cursum: #当最大和等于当前和的时候,比较二者对应子序列长度
  20. if len(shortDict[maxsum]) > len(templist):
  21. shortDict[maxsum] = templist[:]
  22. return shortDict[maxsum]

在这里,有个比较有意思的点:

假设我把某列表复制给了字典某键对应的值:tempDict[key] = templist, 然后再对该列表进行操作,则这个字典的键对应的值也会发生改变!因为直接使用等号+列表名浅复制,只是把列表的地址复制给了字典,所以对列表的任何改变都会导致dict的改变!

我需要做的就是对列表进行深复制~ 深复制的方法很简单:

方法1.

  1. 简单列表的拷贝
  2. 已知一个列表,求生成一个新的列表,列表元素是原列表的复制
  3. a=[1,2]
  4. b=a[:]
  5. 这样, 修改ab没有影响。修改ba没有影响。

方法2.

  1. 可以使用copy模块中的deepcopy函数。修改测试如下:
  2. import copy
  3. a=[1,2]
  4. b=copy.deepcopy(a)

leetcode算法刷题(四)——动态规划(二)的更多相关文章

  1. leetcode算法刷题(五)——动态规划(三)

    今天的题目不是leetcode上面的.只是觉得动态规划还是不算很熟练,就接着找了点DP的题练练 最长递增子序列的长度 题目的意思:传入一个数组,要求出它的最长递增子序列的长度.例如:如在序列1,-1, ...

  2. leetcode 算法刷题(一)

    今天开始刷Leetcode上面的算法题.我会更新我刷题过程中提交的代码(成功和不成功的都有)和比较好的解法 第二题 Add Two Numbers 题目的意思:输入两个链表,这两个链表都是倒序的数字, ...

  3. leetcode算法刷题(二)——动态规划(一)

    上次刷了五六道题,都是关于string处理的,这次想换个知识点刷一下,然后再回头刷string的题,当做复习.. 这几天主要会选择动态规划的题目,因为以前从没刷过这方面的东西,很多东西都不是很懂..就 ...

  4. leetcode算法刷题(三)

    今天在刷了几道简单的动态规划后,又看了看string方面的题 第五题 Longest Palindromic Substring 题目的意思:求一个字符串的最长回文子串 分析:开始,我的想法是,现在字 ...

  5. Leetcode算法刷题:217和219题 Contains Duplicate

    从题目名字就可以看出这两道题是相似的,219是217的加强版 217:Contains Duplicate 题目 给予一个数组,判断是否有重复的元素.如果有就返回True,没有就返回False.以下是 ...

  6. Leetcode算法刷题:第100题 Same Tree

    Same Tree 题目 给予两棵二叉树,判断这两棵树是否相等(即各节点的值都一样) 解题思路 分别遍历两棵二叉树,并用列表分别存储这两棵树的节点的值,比较这两个列表就可以了 class Soluti ...

  7. Leetcode算法刷题:第14题 Longest Common Prefix

    Longest Common Prefix 题目 给予一个列表,元素为字符串,写一个程序找出最长公共前缀 解题思路 先比较两个字符串,如果第一个字符不一样,则返回空值,比较完成后,用这个公共字符串和下 ...

  8. Leetcode算法刷题:第112题 Path Sum

    Path Sum 题目 给予一个二叉树,和一个值su,寻找是否有一个从根节点到叶节点的和为su,有则返回True,没有为False.比如: 5 / \ 4 8 / / \ 11 13 4 / \ \ ...

  9. leetcode top-100-liked-questions刷题总结

    一.起因 宅在家中,不知该做点什么.没有很好的想法,自己一直想提升技能,语言基础自不必言,数据结构还算熟悉,算法能力一般.于是乎,就去刷一通题. 刷题平台有很多,我选择了在leetcode进行刷题.回 ...

随机推荐

  1. JS 中刷新页面的方法

    整理了就是这几种,,有些在IE下面是不支持的,慎用... 1,history.go(0) 2,location.reload() 3,location=location 4,location.assi ...

  2. 生成shadow中hash字串

    [root@master base]# openssl passwd -1 -salt 123Password: $1$123$2rm.J6pr3p.rmj6YoKSQ8.[root@master b ...

  3. phonegap安卓环境下使用BarcodeScanner插件扫描二维码教程

    由于一直在使用phoneGap来开发安卓应用,而对于原生Java小白的我最近这几天一直陷入了如何使用phonegap的BarcodeScanner插件这件事情上,可以说查遍了百度和Google,虽然只 ...

  4. 第一章——Activity的生命周期

    问题总结: 1.Activity完整的生命周期 2.当打开第二个Activity并关闭时候的生命周期. ①.解释为什么onPause()方法不要有耗时操作 3.Activity发生异常重启的时候问题: ...

  5. Oracle EBS-SQL (PO-14):检查供应商信息sql

    select pvs.org_id, pvs.vendor_id, pvs.vendor_site_id, hou.name                                 经营组织, ...

  6. 时间TDateTime相当于是Double,即双精度数64位,终于查到它用11位表示e,53位表示精度(整数小数一起),最前面一位表示正负

    http://docwiki.embarcadero.com/RADStudio/Seattle/en/Internal_Data_Formats 关于Double的RTL函数,好像就一个:TrySt ...

  7. 载入OpenSSL的动态库——学会使用tryToLoadOpenSslWin32Library和QPair

    Libraries name of openssl? The "library" portion of OpenSSL consists of two libraries. On ...

  8. 文艺编程 Literate Programming

    (译注:这篇文章是 Donald Knuth 一篇1983年的论文:Literate Programming 的介绍部分.有人翻译为“字面编程”,是极其错误的说法,literate 根本就没有“字面” ...

  9. SQL连接方式(内连接,外连接,交叉连接)

    1.内连接.左连接.右连接.全连接介绍 內连接仅选出两张表中互相匹配的记录.因此,这会导致有时我们需要的记录没有包含进来.内部连接是两个表中都必须有连接字段的对应值的记录,数据才能检索出来.   左连 ...

  10. linux 命令总结(转载)

    linux 命令总结(转载) 1. 永久更改ip ifconfig eth0 新ip 然后编辑/etc/sysconfig/network-scripts/ifcfg-eth0,修改ip 2.从Lin ...