leetcode-Maximum Subarray
https://leetcode.com/problems/maximum-subarray/
Find the contiguous subarray within an array (containing at least one number) which has the largest sum.
For example, given the array
[−2,1,−3,4,−1,2,1,−5,4]
,
the contiguous subarray[4,−1,2,1]
has the largest sum =6
.
这道题的题意是要我们找到一个子串,这个子串的和是所有子串里面最大的。返回子串的和。
我当时最大的失误就是把题意看成为了返回当前子串的头下标。。(题目说找到子串,find xx array 但却又返回的是一个数字,确实让我的智商捏了一把汗。。)看题目太粗心,以后这个细节一定要注意。
解题思路:
首先,我们发现这道题目的标签是为动态规划,那么动态规划的简单思想就是把一道问题分成小的阶段,我们只要求出当前阶段最优的结果,一步一步就可以解得正确地答案。
所以当前我们需要找到和为最大的子串,怎样才能把它分成几段呢?是分成以不同下标开头的子串分别计算呢还是怎么样?如何想明白这里,确实需要一定的数学素养,像我就没有想出来。。既然我现在已经知道解题思路了,我还是争取以最自然的方法把解题的思路慢慢道来,不让读者觉得很突兀。
既然题目已经标明这个问题是可以动态规划的方法来进行解决了,而我们一时却又想不出个解题的方法,想必我们可以好好的去看看动态规划的具体定义,看从中能不能得到什么启发,下面这一段摘自百度百科动态规划的定义:
20世纪50年代初美国数学家R.E.Bellman等人在研究多阶段决策过程(multistep decision process)的优化问题时,提出了著名的最优化原理(principle of optimality),把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解,创立了解决这类过程优化问题的新方法——动态规划。
这一句道出动态规划的基本思想,不过貌似对现在没找到解题方案的我们并没有什么帮助。继续往下看:
虽然动态规划主要用于求解以时间划分阶段的动态过程的优化问题,但是一些与时间无关的静态规划(如线性规划、非线性规划),只要人为地引进时间因素,把它视为多阶段决策过程,也可以用动态规划方法方便地求解。
这里我们发现他提到了对于静态规划,时间因素往往可能是不存在的,需要我们人为的引入,那么就我们当前的这个题目来讲是不是有点类似呢?
当前我们可以把我们自己的题目写成这样一种形式:MaxSubarray(list),乍一看这哪里有什么时间因素呢?哪来的阶段呢?人为添加时间因素怎么加?我们可不可以先这样试试:MaxSubarray(list, time),看起是有点怪怪的,不过改一下会不会看得习惯一些?MaxSubarray(list , i),诶。这里面的i是不是给了我们无限的遐想?i可以是什么呢?
如果我们现在将函数假设成了上述的样子,我们就可以让time从小变到大,最终能解得我们所需要的答案。什么东西可以从小变到大呢,如果我想成每个不同下标所打头的子序列可不可以,这样好像变成了一种迭代方法,而不是动态规划,而且他们相互之间似乎并没有状态的联系。不知道到这里大家有没有想到,如果time是指我们给定列表的长度会怎样,我们先求出短列表中和和最大子序列,然后再给列表添加一个元素,然后再求它当前的和最大子序列。
如果当前列表的最大子序列已经找到,那么我们添加一个元素后其最大子列表应该有三种情况,一种是维持原状,仍然是之前的最大子序列;一种是添加的元素够大,一枝独秀,直接就是长度为1的她自己;最后一种情况可能大家不太好想,就是包含之前最大子序列还有之后的元素直到新添加元素为止,这样一个子序列。
针对第三种情况简单描述一下: [当前最大子序列],[最大子序列后面的元素],[新加入的元素]
+ - +
我们可以知道,【最大子序列后面的元素】+【当前最大子序列】<【当前最大子序列】,也就是说【最大子序列后面的元素】<0;如果新加入的元素为正的话,那么【最大子序列后面的元素】 = 【最大子序列后面的元素】+【新加入的元素】这个结果不一定小于零,也就是说,新加入元素后的最大子序列将变为【当前最大子序列】+【最大子序列后面的元素】+【新加入的元素】。
好了这样一来,我们就可以上代码了!python祭上:
class Solution:
# @param {integer[]} nums
# @return {integer}
def maxSubArray(self, nums):
sofar = nums[0]
newend = nums[0]
for i in range(1,len(nums)):
newend = max(nums[i], newend+nums[i])
sofar = max(sofar, newend)
return sofar
最后贴上百度百科动态规划的另一段话:
动态规划程序设计是对解最优化问题的一种途径、一种方法,而不是一种特殊算法。不像搜索或数值计算那样,具有一个标准的数学表达式和明确清晰的解题方法。动态规划程序设计往往是针对一种最优化问题,由于各种问题的性质不同,确定最优解的条件也互不相同,因而动态规划的设计方法对不同的问题,有各具特色的解题方法,而不存在一种万能的动态规划算法,可以解决各类最优化问题。因此读者在学习时,除了要对基本概念和方法正确理解外,必须具体问题具体分析处理,以丰富的想象力去建立模型,用创造性的技巧去求解。我们也可以通过对若干有代表性的问题的动态规划算法进行分析、讨论,逐渐学会并掌握这一设计方法。
共勉
leetcode-Maximum Subarray的更多相关文章
- [array] leetcode - 53. Maximum Subarray - Easy
leetcode - 53. Maximum Subarray - Easy descrition Find the contiguous subarray within an array (cont ...
- 小旭讲解 LeetCode 53. Maximum Subarray 动态规划 分治策略
原题 Given an integer array nums, find the contiguous subarray (containing at least one number) which ...
- LeetCode 53. Maximum Subarray(最大的子数组)
Find the contiguous subarray within an array (containing at least one number) which has the largest ...
- 【leetcode】Maximum Subarray (53)
1. Maximum Subarray (#53) Find the contiguous subarray within an array (containing at least one nu ...
- 【leetcode】Maximum Subarray
Maximum Subarray Find the contiguous subarray within an array (containing at least one number) which ...
- leetCode 53.Maximum Subarray (子数组的最大和) 解题思路方法
Maximum Subarray Find the contiguous subarray within an array (containing at least one number) whic ...
- 41. leetcode 53. Maximum Subarray
53. Maximum Subarray Find the contiguous subarray within an array (containing at least one number) w ...
- Leetcode#53.Maximum Subarray(最大子序和)
题目描述 给定一个序列(至少含有 1 个数),从该序列中寻找一个连续的子序列,使得子序列的和最大. 例如,给定序列 [-2,1,-3,4,-1,2,1,-5,4], 连续子序列 [4,-1,2,1] ...
- LN : leetcode 53 Maximum Subarray
lc 53 Maximum Subarray 53 Maximum Subarray Find the contiguous subarray within an array (containing ...
随机推荐
- oracle sql 语句优化
(1)选择最有效率的表名顺序(只在基于规则的优化器中有效):Oracle的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table)将被最先处理 ...
- python爬虫——爬取NUS-WIDE数据库图片
实验室需要NUS-WIDE数据库中的原图,数据集的地址为http://lms.comp.nus.edu.sg/research/NUS-WIDE.htm 由于这个数据只给了每个图片的URL,所以需 ...
- java四大域总结
最近学完了web部分,发现有些地方总是单个容易理解,可是把所有的放在一起来大杂烩,总是有那么几个知识点容易混淆.其实网上的资料已经够多了,虽然也不乏辛劳的搬运工.可是最终的目的不就是要我们自身理解吗? ...
- Java中处理异常throw和throws
1.首先我们来了解什么是异常呢? 异常阻止当前方法或作用域继续执行的问题. 2.处理异常 说到处理异常,我们当然会想到 try catch finally 在java中我们会对异常的处理有更高的认识 ...
- Android:TextView 自动滚动(跑马灯) (转)
Android:TextView 自动滚动(跑马灯) TextView实现文字滚动需要以下几个要点: 1.文字长度长于可显示范围:android:singleLine="true ...
- OC中几种集合的遍历方法(数组遍历,字典遍历,集合遍历)
// 先分别初始化数组.字典和集合,然后分别用for循环.NSEnumerator枚举器和forin循环这三个方法来实现遍历 NSArray *array = @[@"yinhao" ...
- ReactiveCocoa之UI篇
前言: 上一篇讲ReactiveCocoa是函数响应式编程,并将多种事件响应的方式统一起来,使得不同的事件响应方式高度统一.同时也讲了ReactiveCocoa框架里面常见的几个概念.接下来基于那几个 ...
- IOS开发--仿制网易新闻
学习来源:袁峥老师的<快速集成App中顶部标题滚动条> 此次博文写的是按需求分析写代码,思路条理性杠杠的,可以提高的编码实现速度哦. 效果: 根据这个网易新闻的界面,需求分析: ...
- js 字符串转 数字
<html> <body> <script language="javascript"> var a = "0.11"; v ...
- MongoDb的bin目录下文件mongod,mongo,mongostat命令的说明及使用
MongoDB的下载地址:http://www.mongodb.org/downloads. 下载好直接解压安装包,即可使用. bin目录下的几个文件说明: mongo 客户端程序,连接MongoDB ...