Leetcode——53.最大子序和
@author: ZZQ
@software: PyCharm
@file: leetcode53_最大子序和.py
@time: 2018/11/26 12:39
要求:给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
方法如下:
方法一:暴力遍历法——O(n2)
class Solution():
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
nums_len = len(nums)
if nums_len == 0:
return 0
if nums_len == 1:
return nums[0]
max_value = nums[0]
for i in range(nums_len):
temp_max = 0
for j in range(i, nums_len):
temp_max += nums[j] # 大量的重复运算,拖慢速度
max_value = max(max_value, temp_max)
return max_value
方法二:基于方法一避免大量的重复运算 ——O(n2)
class Solution():
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
nums_len = len(nums)
temp_sum = [0]*(nums_len+1)
if nums_len == 0:
return 0
if nums_len == 1:
return nums[0]
max_value = nums[0]
for i in range(nums_len): # 基于方法一,避免大量的重复运算
temp_sum[i] = temp_sum[i-1] + nums[i]
for i in range(nums_len):
for j in range(i, nums_len):
temp_max = temp_sum[j] - temp_sum[i-1]
max_value = max(max_value, temp_max)
return max_value
方法三:分治法——O(nlogn)
将求长度为n的序列中的最大子序和华为分求两个长度为n/2的序列的最大子序和
将当前需要计算最大子串的序列分为两半,
前半段从后往前遍历求最大子串lmax,
后半段从前往后遍历求最大子串rmax,
lmax+rmax就是当前长度为n的序列的最大子串,
然后递归去找长度为n/2的序列的最大子串和,不断求小的序列的子串和。
最后进行比较,得出最大值就是所求结果。
class Solution():
def maxSubArray3(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
nums_len = len(nums)
if nums_len == 0:
return 0
left = 0
right = nums_len - 1
ans = self.maxSubArrayCompute(nums, left, right)
return ans
def maxSubArrayCompute(self, nums, left, right):
"""
:type nums: List[int]
:type left: int
:type right: int
:rtype: int
"""
if left > right:
return 0
if left == right:
return nums[left]
middle = (left + right)/2
left_max = self.maxSubArrayCompute(nums, left, middle)
right_max = self.maxSubArrayCompute(nums, middle+1, right)
lmax = nums[middle]
left_sum = nums[middle]
# 保证求得到子序列是连续的(也就是lmax + rmax是一个连续子序列的和)
for i in range(middle-1, left-1, -1): # 前半段逆序加(range(left,right,-1)表示逆序遍历)
left_sum += nums[i]
lmax = max(lmax, left_sum)
rmax = nums[middle+1]
right_sum = nums[middle+1]
for i in range(middle+2, right+1): # 后半段顺序加
right_sum += nums[i]
rmax = max(rmax, right_sum)
return max(rmax+lmax, max(left_max, right_max))
方法四:扫描法——O(n)
当我们加上一个正数时,和会增加;
当我们加上一个负数时,和会减少。
如果当前得到的和是个负数,那么这个和在接下来的累加中应该抛弃并重新清零,不然的话这个负数将会减少接下来的和。
class Solution():
def maxSubArray(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
nums_len = len(nums)
current = nums[0]
nums_sum = nums[0]
# 我们考虑如果全是负数,那么返回最大的负数,如果最后的和为正,那么就使用扫描法
for i in range(1, nums_len):
if current < 0:
current = nums[i] # 当前数小于0 肯定会舍去(否则将会影响接下来的和),换为下一个数
else:
current += nums[i] # 如果当前数不小于0,那么他会对接下来的和有积极影响
if current > nums_sum:
nums_sum = current # 这里既实现了负数返回最大也实现了扫描法
#这里其实已经隐式的列举了所有可能,保留了所有可能的最大值
return nums_sum
方法五:动态规划——O(n)
假设sum[i]为以i结尾的连续子串的和. 假设对于元素i,所有以它前面的元素结尾的子串和都已经求得,
那么以第i个元素结尾且和最大的连续子串实际上,
1)要么是以第i-1个元素结尾且和最大的连续子数组加上这个元素,
2)要么只是第i个元素,即sum[i]
所以当前的最大连续子串和的计算方法是max(sum[i-1]+nums[i], nums[i])
这就是需要我们判断sum[i-1]是否大于0。
由于每次运算只需要前一次的结果,因此算法的时间和空间复杂度都很小。
class Solution():
def maxSubArray5(self, nums): # 动态规划
"""
:type nums: List[int]
:rtype: int
"""
nums_len = len(nums)
if nums_len == 0:
return 0
if nums_len == 1:
return nums[0]
nums_sum = nums[0]
pre = nums[0]
for i in range(1, nums_len):
if pre > 0:
pre += nums[i]
else:
pre = nums[i]
nums_sum = max(nums_sum, pre)
return nums_sum
Leetcode——53.最大子序和的更多相关文章
- LeetCode 53. 最大子序和(Maximum Subarray)
53. 最大子序和 53. Maximum Subarray 题目描述 给定一个整数数组 nums,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和. LeetCode53. M ...
- Java实现 LeetCode 53 最大子序和
53. 最大子序和 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和. 示例: 输入: [-2,1,-3,4,-1,2,1,-5,4], 输出: 6 ...
- Leetcode之动态规划(DP)专题-53. 最大子序和(Maximum Subarray)
Leetcode之动态规划(DP)专题-53. 最大子序和(Maximum Subarray) 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和. ...
- leetcode 120. 三角形最小路径和 及 53. 最大子序和
三角形最小路径和 问题描述 给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [ [2], [3,4], [6,5,7], [4,1,8,3] ] ...
- 1. 线性DP 53. 最大子序和.
53. 最大子序和. https://leetcode-cn.com/problems/maximum-subarray/ func maxSubArray(nums []int) int { dp ...
- 53. 最大子序和(剑指 Offer 42)
53. 最大子序和(剑指 Offer 42) 知识点:数组:前缀和:哨兵:动态规划:贪心:分治: 题目描述 输入一个整型数组,数组中的一个或连续多个整数组成一个子数组.求所有子数组的和的最大值. 要求 ...
- 【LeetCode】53.最大子序和
最大子序和 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和. 示例: 输入: [-2,1,-3,4,-1,2,1,-5,4], 输出: 6 解释: ...
- Leetcode题目53.最大子序和(动态规划-简单)
题目描述: 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和. 示例: 输入: [-2,1,-3,4,-1,2,1,-5,4],输出: 6解释: 连 ...
- leetcode之53.最大子序和
题目详情 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和. 示例: 输入: [-2,1,-3,4,-1,2,1,-5,4], 输出: 6 解释: ...
随机推荐
- 2019年京东Java研发岗社招面经(面试经历+真题总结+经验分享)!
本篇先以日历形式回顾秋招之路,方便各位参考某厂的处理进度:然后是总结归纳春秋招Java面试题库:最后做个总结还有展望,开始新的征程~ 面试经历京东面试真题面试经验分享1.面试经历 2018年的冬季特别 ...
- 使用POI读写Word doc文件
使用POI读写word doc文件 目录 1 读word doc文件 1.1 通过WordExtractor读文件 1.2 通过HWPFDocument读文件 2 写w ...
- Mysql优化_慢查询开启说明及Mysql慢查询分析工具mysqldumpslow用法讲解
Mysql优化_慢查询开启说明及Mysql慢查询分析工具mysqldumpslow用法讲解 Mysql慢查询开启 Mysql的查询讯日志是Mysql提供的一种日志记录,它用来记录在Mysql中响应 ...
- Rinkeby中测试币的申请
https://www.rinkeby.io/#faucet 从这个页面可以看见测试币的请求是有要求的,下面说明怎么做: 之前使用的是google账号,即第二种方式来获取.后面gmail出现了问题,一 ...
- leetcode 199. Binary Tree Right Side View 、leetcode 116. Populating Next Right Pointers in Each Node 、117. Populating Next Right Pointers in Each Node II
leetcode 199. Binary Tree Right Side View 这个题实际上就是把每一行最右侧的树打印出来,所以实际上还是一个层次遍历. 依旧利用之前层次遍历的代码,每次大的循环存 ...
- webpack4升级extract-text-webpack-plugin和UglifyJsPlugin问题
webpack4升级extract-text-webpack-plugin和UglifyJsPlugin问题 1. 使用了extract-text-webpack-plugin插件后,编译出错,代码 ...
- ubuntu 安装json
命令行中输入:sudo apt-get install libjsoncpp-dev
- 学习CSS布局 - box-sizing
box-sizing 人们慢慢的意识到传统的盒子模型不直接,所以他们新增了一个叫做 box-sizing 的CSS属性. 当你设置一个元素为 box-sizing: border-box; 时,此元素 ...
- AIS系统(转)
船舶自动识别系统(Automatic Identification System, 简称AIS系统)由岸基(基站)设施和船载设备共同组成,是一种新型的集网络技术.现代通讯技术.计算机技术.电子信息显示 ...
- ASP.NET web.config中数据库连接字符串connectionStrings节的配置方法
ASP.NET web.config中数据库连接字符串connectionStrings节的配置方法 第一种情况,本地开发时,使用本地数据库,如下面的代码 <connectionStrings& ...