题目描述

给定一个序列(至少含有 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。可以很容易想到:

  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]一步一步地进行。

思路二:

遍历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(最大子序和)的更多相关文章

  1. LeetCode 53. Maximum Subarray最大子序和 (C++)

    题目: Given an integer array nums, find the contiguous subarray (containing at least one number) which ...

  2. 【LeetCode】53. Maximum Subarray 最大子序和 解题报告(Python & C++ & Java)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 暴力解法 动态规划 日期 题目地址: https:/ ...

  3. [LeetCode] 53. Maximum Subarray 最大子数组

    Given an integer array nums, find the contiguous subarray (containing at least one number) which has ...

  4. [leetcode]53. Maximum Subarray最大子数组和

    Given an integer array nums, find the contiguous subarray (containing at least one number) which has ...

  5. 53. Maximum Subarray最大子序和

    网址:https://leetcode.com/problems/maximum-subarray/submissions/ 很简单的动态规划 我们可以把 dp[i] 表示为index为 i 的位置上 ...

  6. 【LeetCode】Maximum Subarray(最大子序和)

    这道题是LeetCode里的第53道题. 题目描述: 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和. 示例: 输入: [-2,1,-3,4,-1 ...

  7. [LeetCode] 53. Maximum Subarray 最大子数组 --动态规划+分治

    Given an integer array nums, find the contiguous subarray (containing at least one number) which has ...

  8. [array] leetcode - 53. Maximum Subarray - Easy

    leetcode - 53. Maximum Subarray - Easy descrition Find the contiguous subarray within an array (cont ...

  9. 小旭讲解 LeetCode 53. Maximum Subarray 动态规划 分治策略

    原题 Given an integer array nums, find the contiguous subarray (containing at least one number) which ...

随机推荐

  1. TP5.0+小程序商城构建(1)

    1.导语 1.整体的思路与编程思想(大局观.AOP面向切面编程,10-20%) 2.具体的编程知识与技巧(TP5.小程序.数据库等80%) 2.课程内容与产品技术点 1.ThinkPHP5框架 1.编 ...

  2. JMeter-Java压力测试工具-01

    先去官网下载 打开 下面测试一个小栗子 建立一个工程,提供一个查询接口 package com.example.demo; import org.springframework.web.bind.an ...

  3. Luogu P3254 圆桌问题

    题目链接 \(Click\) \(Here\) 水题.记得记一下边的流量有没有跑完. #include <bits/stdc++.h> using namespace std; const ...

  4. spring boot 返回json字符串 null值转空字符串

    @Configuration public class JacksonConfig { @Bean @Primary @ConditionalOnMissingBean(ObjectMapper.cl ...

  5. 2017-12-14python全栈9期第一天第四节之python分类

    python的环境. 编译型:一次性将所有程序编译成二进制文件. 缺点:开发效率低,不能跨平台. 优点:运行速度快. :C,C++等等. 解释型:当程序执行时,一行一行的解释. 优点:开发效率高,可以 ...

  6. Zabbix Server 自带模板监控无密码MySQL数据库

    Zabbix Server 自带模板监控无密码MySQL数据库 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.  一.安装MariaDB 1>.安装MariaDB  [root ...

  7. 端口与进程-----Window cmd命令

    ********************  windows 篇 ********************** cmd命令: services.msc    打开本地服务页面 一.查看windows系统 ...

  8. VS2015快捷键大全

    Ctrl+E,D —-格式化全部代码 Ctrl+E,F —-格式化选中的代码 CTRL + SHIFT + B生成解决方案 CTRL + F7 生成编译 CTRL + O 打开文件 CTRL + SH ...

  9. idea使用maven打包项目

    第一步:打开maven Projects 第二步.找到package 第三步,运行.到路径下面去找打包的文件吧. 第二种方法: 使用命令 cmd进入项目目录,例如项目在D盘项目名poject 输入: ...

  10. HDU - 6393 Traffic Network in Numazu(树链剖分+基环树)

    http://acm.hdu.edu.cn/showproblem.php?pid=6393 题意 给n个点和n条边的图,有两种操作,一种修改边权,另一种查询u到v的最短路. 分析 n个点和n条边,实 ...