每日一题 - 剑指 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: 总结:
随机推荐
- 第四届蓝桥杯JavaC组国(决)赛真题
解题代码部分来自网友,如果有不对的地方,欢迎各位大佬评论 题目1.好好学习 汤姆跟爷爷来中国旅游.一天,他帮助中国的小朋友贴标语.他负责贴的标语是分别写在四块红纸上的四个大字:"好.好.学. ...
- Java实现最优二叉查找树
1 问题描述 在了解最优二叉查找树之前,我们必须先了解何为二叉查找树? 引用自百度百科一段讲解: 二叉排序树(Binary Sort Tree)又称二叉查找树(Binary Search Tree), ...
- 温故知新-多线程-深入刨析CAS
文章目录 摘要 CAS是什么? CAS是如何实现的? CAS存在的问题? 你的鼓励也是我创作的动力 Posted by 微博@Yangsc_o 原创文章,版权声明:自由转载-非商用-非衍生-保持署名 ...
- Linux: ssh命令 远程登录
1.查看SSH客户端版本 使用ssh -V命令可以得到版本号.需要注意的是,Linux一般自带的是OpenSSH; $ ssh -V ssh: SSH Secure Shell 3.2.9.1 (no ...
- hql 转 sql
import org.hibernate.engine.SessionFactoryImplementor; import org.hibernate.hql.ast.QueryTranslatorI ...
- flutter-web利用dart js 库发起http request
初学flutter,初学前端,尝试在dart中直接使用HttpClient时,直接报出Platform not supported,查资料发现他还不支持浏览器. 通过查阅资料发现可以借助axios 与 ...
- Flask URL构建
Flask URL构建 url_for()函数对于动态构建特定函数的URL非常有用.该函数接受函数的名称作为第一个参数,以及一个或多个关键字参数,每个参数对应于URL的变量部分. 以下脚本演示了如何使 ...
- 综合练习: PIVOT、UNPIVOT、GROUPING SETS、GROUPING_ID_1
综合练习: PIVOT.UNPIVOT.GROUPING SETS.GROUPING_ID 问题1:Desired output: empid cnt2007 cnt2008 cnt2009 ---- ...
- 关联函数-web_save_param_length
int web_save_param_length(const char * Param,const char * Base,LAST); 参数说明: Param:保存长度的参数的名称. Base:参 ...
- Android开发学习笔记DDMS的使用
打开DDMS DDMS 的全称是Dalvik Debug Monitor Service,是 Android 开发环境中的Dalvik虚拟机调试监控服务. DDMS里面包含了:Device(设备) F ...