Leetcode#53.Maximum Subarray(最大子序和)
题目描述
给定一个序列(至少含有 1 个数),从该序列中寻找一个连续的子序列,使得子序列的和最大。
例如,给定序列 [-2,1,-3,4,-1,2,1,-5,4],
连续子序列 [4,-1,2,1] 的和最大,为 6。
扩展练习:
若你已实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。
思路
思路一:
maxSum 必然是以nums[i](取值范围为nums[0] ~ nums[n-1])结尾的某段构成的,也就是说maxSum的candidate必然是以nums[i]结果的。如果遍历每个candidate,然后进行比较,那么就能找到最大的maxSum了。
假设把nums[i]之前的连续段叫做sum。可以很容易想到:
- 如果sum>=0,就可以和nums[i]拼接在一起构成新的sum。因为不管nums[i]多大,加上一个正数总会更大,这样形成一个新的candidate。
- 反之,如果sum<0,就没必要和nums[i]拼接在一起了。因为不管nums[i]多小,加上一个负数总会更小。此时由于题目要求数组连续,所以没法保留原sum,所以只能让sum等于从nums[i]开始的新的一段数了,这一段数字形成新的candidate。
- 如果每次得到新的candidate都和全局的maxSum进行比较,那么必然能找到最大的max sum subarray.
在循环过程中,用maxSum记录历史最大的值。从nums[0]到nums[n-1]一步一步地进行。
思路二:
遍历array,对于每一个数字,我们判断,(之前的sum + 这个数字) 和 (这个数字) 比大小,如果(这个数字)自己就比 (之前的sum + 这个数字) 大的话,那么说明不需要再继续加了,直接从这个数字,开始继续,因为它自己已经比之前的sum都大了。
反过来,如果 (之前的sum + 这个数字)大于 (这个数字)就继续加下去。
利用动态规划做题。
只遍历数组一遍,当从头到尾部遍历数组A, 遇到一个数有两种选择 (1)加入之前subArray (2)自己另起一个subArray
设状态S[i], 表示以A[i]结尾的最大连续子序列和,状态转移方程如下:
S[i] = max(S[i-1] + A[i],A[i])
从状态转移方程上S[i]只与S[i-1]有关,与其他都无关,因此可以用一个变量来记住前一个的最大连续数组和就可以了。这样就可以节省空间了。
代码实现
package Array;
/**
* 53.Maximum Subarray(最大子序和)
* 给定一个序列(至少含有 1 个数),从该序列中寻找一个连续的子序列,使得子序列的和最大。
* 例如,给定序列 [-2,1,-3,4,-1,2,1,-5,4],
* 连续子序列 [4,-1,2,1] 的和最大,为 6。
*/
public class Solution53 {
public static void main(String[] args) {
Solution53 solution53 = new Solution53();
int[] arr = {-2, 1, -3, 4, -1, 2, 1, -5, 4};
System.out.println(solution53.maxSubArray(arr));
}
/**
* maxSum 必然是以nums[i](取值范围为nums[0] ~ nums[n-1])结尾的某段构成的,也就是说maxSum的candidate必然是以nums[i]结果的。如果遍历每个candidate,然后进行比较,那么就能找到最大的maxSum了。
* 假设把nums[i]之前的连续段叫做sum。可以很容易想到:
* 1. 如果sum>=0,就可以和nums[i]拼接在一起构成新的sum。因为不管nums[i]多大,加上一个正数总会更大,这样形成一个新的candidate。
* 2. 反之,如果sum<0,就没必要和nums[i]拼接在一起了。因为不管nums[i]多小,加上一个负数总会更小。此时由于题目要求数组连续,所以没法保留原sum,所以只能让sum等于从nums[i]开始的新的一段数了,这一段数字形成新的candidate。
* 3. 如果每次得到新的candidate都和全局的maxSum进行比较,那么必然能找到最大的max sum subarray.
* 在循环过程中,用maxSum记录历史最大的值。从nums[0]到nums[n-1]一步一步地进行。
*
* @param nums
* @return
*/
public int maxSubArray(int[] nums) {
int sum = 0; //或者初始化为 sum = INT_MIN 也OK。
int maxSum = nums[0];
for (int i = 0; i < nums.length; i++) {
if (sum >= 0) {
sum += nums[i];
} else {
sum = nums[i];
}
if (sum > maxSum) {
maxSum = sum;
}
}
return maxSum;
}
/**
* 遍历array,对于每一个数字,我们判断,(之前的sum + 这个数字) 和 (这个数字) 比大小,如果(这个数字)自己就比 (之前的sum + 这个数字) 大的话,那么说明不需要再继续加了,直接从这个数字,开始继续,因为它自己已经比之前的sum都大了。
* 反过来,如果 (之前的sum + 这个数字)大于 (这个数字)就继续加下去。
* 利用动态规划做题。
* 只遍历数组一遍,当从头到尾部遍历数组A, 遇到一个数有两种选择 (1)加入之前subArray (2)自己另起一个subArray
* 设状态S[i], 表示以A[i]结尾的最大连续子序列和,状态转移方程如下:
* S[i] = max(S[i-1] + A[i],A[i])
* 从状态转移方程上S[i]只与S[i-1]有关,与其他都无关,因此可以用一个变量来记住前一个的最大连续数组和就可以了。
* 这样就可以节省空间了。
* 时间复杂度:O(n) 空间复杂度:O(1)
*/
public int maxSubArray_2(int[] nums) {
int sum = 0; //或者初始化为 sum = INT_MIN 也OK。
int maxSum = nums[0];
//动态规划
for (int i = 0; i < nums.length; i++) {
sum = Math.max(sum + nums[i], nums[i]);
maxSum = Math.max(sum, maxSum);
}
return maxSum;
}
}
Leetcode#53.Maximum Subarray(最大子序和)的更多相关文章
- LeetCode 53. Maximum Subarray最大子序和 (C++)
题目: Given an integer array nums, find the contiguous subarray (containing at least one number) which ...
- 【LeetCode】53. Maximum Subarray 最大子序和 解题报告(Python & C++ & Java)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 暴力解法 动态规划 日期 题目地址: https:/ ...
- [LeetCode] 53. Maximum Subarray 最大子数组
Given an integer array nums, find the contiguous subarray (containing at least one number) which has ...
- [leetcode]53. Maximum Subarray最大子数组和
Given an integer array nums, find the contiguous subarray (containing at least one number) which has ...
- 53. Maximum Subarray最大子序和
网址:https://leetcode.com/problems/maximum-subarray/submissions/ 很简单的动态规划 我们可以把 dp[i] 表示为index为 i 的位置上 ...
- 【LeetCode】Maximum Subarray(最大子序和)
这道题是LeetCode里的第53道题. 题目描述: 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和. 示例: 输入: [-2,1,-3,4,-1 ...
- [LeetCode] 53. Maximum Subarray 最大子数组 --动态规划+分治
Given an integer array nums, find the contiguous subarray (containing at least one number) which has ...
- [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 ...
随机推荐
- Luogu P4009 汽车加油行驶问题
题目链接 \(Click\) \(Here\) 分层图..好长时间没写差点要忘了\(hhhhh\),其实思路还是很明了的. 注意需要强制消费. #include <bits/stdc++.h&g ...
- Luogu P2463 [SDOI2008]Sandy的卡片
题目链接 \(Click\) \(Here\) 真的好麻烦啊..事实证明,理解是理解,一定要认认真真把板子打牢,不然调锅的时候真的会很痛苦..(最好是八分钟能无脑把\(SA\)码对的程度\(QAQ\) ...
- linux下创建用户组与用户 只能访问指定目录的方法 以及FTP用户配置详解
VSFTPD 安装: -- 查看是否已经安装 VSftpd: rpm -qa | grep vsftp yum install -y vsftpd groupadd ftpuser #创建ftpuse ...
- 基于TC做流量控制
1 模拟延迟传输简介 netem 与 tc: netem 是 Linux 2.6 及以上内核版本提供的一个网络模拟功能模块.该功能模块可以用来在性能良好的局域网中,模拟出复杂的互联网传输性能,诸如低带 ...
- C++ 二维数组作为形参传递使用实例
在线代码编辑器: http://codepad.org/ 1.*指针 void display(int *arr, const int row, const int col) { ; i < r ...
- ubuntu14.04 mysql数据库允许远程访问设置
安装mysql5.5 sudo apt-get install mysql-server-5.5 --------------------------------------------------- ...
- js学习总结:DOM节点一(选择器,节点类型)
DOM:document object model 文档对象模型 DOM就是整个HTML文档的关系图谱(代表整个HTML文档),可以理解为下图: 一.查看元素节点 1.document.getElem ...
- python 调用 java代码
一.JPype简述 1.JPype是什么? JPype是一个能够让 python 代码方便地调用 Java 代码的工具,从而克服了 python 在某些领域(如服务器端编程)中的不足. 2.JPype ...
- 用过企业微信APP 后,微信接收不到消息,解决方案
用过企业微信APP 后,微信接收不到消息的,怎么办? 请打开企业微信,找到:我----设置----新消息通知----仅在企业微信中接收消息
- [Android] Android : lambda expressions are not supported at this language level(需设置project language level)
最近在Github上下载一个别人的开源项目 ,里面用到了Javajdk1.8的新特性:Lambda 表达式.而我用的Android studio发现不能用这个Lambda 表达式. 本地环境: And ...