每日一题 - 剑指 Offer 42. 连续子数组的最大和
题目信息
时间: 2019-06-30
题目链接:Leetcode
tag: 动态规划
难易程度:简单
题目描述:
输入一个整型数组,数组里有正数也有负数。数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。
要求时间复杂度为O(n)。
示例:
输入: nums = [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
提示
1. 1 <= arr.length <= 10^5
2. -100 <= arr[i] <= 100
解题思路
本题难点
| 常见解法 | 时间复杂度 | 空间复杂度 |
|---|---|---|
| 暴力搜索 | O(N^2) | O(1) |
| 分治思想 | O(NlogN) | O(logN) |
| 动态规划 | O(N) | O(1) |
具体思路
动态规划
- 状态定义:设动态规划列表 dp ,dp[i]]代表以元素 nums[i] 为结尾的连续子数组最大和。
- 转移方程: 若 dp[i−1]≤0 ,说明 dp[i−1] 对 dp[i] 产生负贡献,即 dp[i−1]+nums[i] 还不如 nums[i] 本身大。
- 当dp[i-1]>0时,执行dp[i]=dp[i-1] + nums[i]
- 当dp[i-1]<0时,执行dp[i]=nums[i]
- 初始状态:dp[0] = nums[0]
代码
class Solution {
public int maxSubArray(int[] nums) {
if(nums == null || nums.length == 0){
return 0;
}
int sum = nums[0];
int former = 0;//用于记录dp[i-1]的值,对于dp[0]而言,其前面的dp[-1]=0
int cur= nums[0];//用于记录dp[i]的值
for(int num: nums){
if(former <= 0){
cur = num;
}
if(former > 0){
cur = former + num;
}//这两句话等同于 cur = Math.max(former,0) + num;
former = cur;
sum = Math.max(sum,cur);
}
return sum;
}
}
复杂度分析:
- 时间复杂度 O(N) : 线性遍历数组 nums 即可获得结果,使用 O(N) 时间。
- 空间复杂度 O(1) : 使用常数大小的额外空间。
其他优秀解答
解题思路
分治法,我们把数组nums以中间位置(mid)分为左(left)右(right)两部分. 那么有,
left = nums[0]...nums[m - 1] 和 right = nums[m + 1]...nums[n-1]
最大子序列和的位置有以下三种情况:
- 考虑中间元素
nums[m], 跨越左右两部分,这里从中间元素开始,往左求出后缀最大,往右求出前缀最大, 保持连续性。 - 不考虑中间元素,最大子序列和出现在左半部分,递归求解左边部分最大子序列和
- 不考虑中间元素,最大子序列和出现在右半部分,递归求解右边部分最大子序列和
代码
class MaximumSubarrayDivideConquer {
public int maxSubArrayDividConquer(int[] nums) {
if (nums == null || nums.length == 0) return 0;
return helper(nums, 0, nums.length - 1);
}
private int helper(int[] nums, int l, int r) {
if (l > r) return Integer.MIN_VALUE;
int mid = (l + r) >>> 1;
int left = helper(nums, l, mid - 1);
int right = helper(nums, mid + 1, r);
int leftMaxSum = 0;
int sum = 0;
// left surfix maxSum start from index mid - 1 to l
for (int i = mid - 1; i >= l; i--) {
sum += nums[i];
leftMaxSum = Math.max(leftMaxSum, sum);
}
int rightMaxSum = 0;
sum = 0;
// right prefix maxSum start from index mid + 1 to r
for (int i = mid + 1; i <= r; i++) {
sum += nums[i];
rightMaxSum = Math.max(sum, rightMaxSum);
}
// max(left, right, crossSum)
return Math.max(leftMaxSum + rightMaxSum + nums[mid], Math.max(left, right));
}
}
每日一题 - 剑指 Offer 42. 连续子数组的最大和的更多相关文章
- 刷题-力扣-剑指 Offer 42. 连续子数组的最大和
剑指 Offer 42. 连续子数组的最大和 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/lian-xu-zi-shu-zu-de ...
- 剑指 Offer 42. 连续子数组的最大和 + 动态规划
剑指 Offer 42. 连续子数组的最大和 题目链接 状态定义: 设动态规划列表 \(dp\) ,\(dp[i]\) 代表以元素 \(4nums[i]\) 为结尾的连续子数组最大和. 为何定义最大和 ...
- 力扣 - 剑指 Offer 42. 连续子数组的最大和
题目 剑指 Offer 42. 连续子数组的最大和 思路1(分析数组的规律) 我们可以从头到尾逐个累加,若之前的累加和小于0,那就从丢弃之前的累加,从当前开始重新累加,同时在遍历过程中比较记录下最大值 ...
- 【Java】 剑指offer(42) 连续子数组的最大和
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 输入一个整型数组,数组里有正数也有负数.数组中一个或连续的多个整/ ...
- 剑指 Offer 42. 连续子数组的最大和
题目描述 输入一个整型数组,数组中的一个或连续多个整数组成一个子数组.求所有子数组的和的最大值. 要求时间复杂度为\(O(n)\). 示例1: 输入: nums = [-2,1,-3,4,-1,2,1 ...
- 【剑指Offer】连续子数组的最大和 解题报告(Python)
[剑指Offer]连续子数组的最大和 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interviews ...
- 《剑指Offer》- 连续子数组的最大和或最小和
前言 本文是<剑指Offer>系列(JavaScript版)的第一篇,题目是"连续子数组的最大和或最小和". 话不多说,开始"打怪"修炼... 一. ...
- Go语言实现:【剑指offer】连续子数组的最大和
该题目来源于牛客网<剑指offer>专题. HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向 ...
- 《剑指offer》连续子数组的最大和
本题来自<剑指offer> 反转链表 题目: 思路: C++ Code: Python Code: 总结:
随机推荐
- 在已经编译安装好php7场景下,install gd库 with free-type (解决Call to undefined function imagettftext())
在已经编译安装好php7场景下,install gd库 with free-type (解决Call to undefined function imagettftext()) install g ...
- spring Cloud服务注册中心Eureka集群
spring Cloud服务注册中心Eureka集群配置: 在application.yml文件加以下配置: server: port: 8761 tomcat: uri-encoding: UTF- ...
- 手把手教你用redis实现一个简单的mq消息队列(java)
众所周知,消息队列是应用系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构.目前使用较多的消息队列有 ActiveMQ,RabbitMQ,Zero ...
- 两条命令实现nodejs快速安装
操作系统: debian, ubuntu, fedora 当前版本: v14.4.0 一键安装命令: curl -sL https://deb.nodesource.com/setup_14.x | ...
- Centos 7 k8s Deployment新副本控制器
一.概念 Kubernetes提供了一种更加简单的更新RC和Pod的机制,叫做Deployment.通过在Deployment中描述你所期望的集群状态,Deployment Controller会将在 ...
- Js中Array 函数使用方法
遇到数组有关操作,脑子第一反应不要再是嵌套 for 循环了,Array 类型提供了一些遍历有关的函数. Array.prototype.forEach() : 把数组每个元素丢到一个处理 functi ...
- flutter-web利用dart js 库发起http request
初学flutter,初学前端,尝试在dart中直接使用HttpClient时,直接报出Platform not supported,查资料发现他还不支持浏览器. 通过查阅资料发现可以借助axios 与 ...
- linu使用x之sz下载和rz上传
对于经常使用Linux系统的人员来说,少不了将本地的文件上传到服务器或者从服务器上下载文件到本地,rz / sz命令很方便的帮我们实现了这个功能,但是很多Linux系统初始并没有这两个命令.今天,我们 ...
- CentOS7.5搭建Kafka2.11-1.1.0集群与简单测试
一.下载 下载地址: http://kafka.apache.org/downloads.html 我这里下载的是Scala 2.11对应的 kafka_2.11-1.1.0.tgz 二.集群规 ...
- filter()函数过滤序列
''' Python内建的filter()函数用于过滤序列. 和map()类似,filter()也接收一个函数和一个序列.和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据 ...