题目:和最大的子序列

难度:Medium

题目内容

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

翻译

给定一个整数数组nums,找到相邻的子数组(至少包含一个数字),它的总和是最大的,并返回它的和。

Example:

Input: [-2,1,-3,4,-1,2,1,-5,4],
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.

Follow up:

If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.

我的思路:呃,没啥好思路,只会硬刚两个for,遍历所有子序列。。

我的代码:

     public int maxSubArray(int[] nums) {
int max = nums[0];
for (int i = 0; i < nums.length; i++) {
int sum = 0;
for (int j = i; j < nums.length; j++) {
sum += nums[j];
max = sum > max ? sum : max;
}
}
return max;
}

我的复杂度:O(n2

编码过程中的问题:(简单地代码有时候问题也是挺多的,可见并不能偷懒,想到方法了即使很简单也要动手写才行)

1、一开始取max 的初值为 0,然后发现当只有一个负数的时候会返回0,所以遍历取最值的时候,max或者min的初值应该取数组内部的值;

2、一开始sum的初值取的是 nums[i], j 从 i + 1 开始,然后发现最后一个元素(也是一个子序列)不会进入判断,所以遍历所有子序列的时候 j 应该是从 i 开始,sum的初值取0;

答案代码

     public int maxSubArray(int[] nums) {
int n = nums.length;
int[] dp = new int[n];
dp[0] = nums[0];
int max = dp[0]; for(int i = 1; i < n; i++){
dp[i] = Math.max(dp[i-1] + nums[i], nums[i]);
max = Math.max(max, dp[i]);
} return max;
}

答案复杂度:O(N)

答案思路:采用动态规划的思想,新建一个数组,用它来记录以 nums[i] 结尾的序列能达到的最大值。

取 nums[i] 与 nums[i] + dp[i-1]的最大值就行(dp[i-1]如果大于零,则直接加,否则取nums[i]即为最大)

【注意并不是说dp[i]就表示以nums[i]结尾的序列内子序列能达到的最大值】

所以 dp[] 里面最大的那一个值就是要求的最大的。

优化:

因为只要知道dp的最大值即可,所以不需要把dp新建出来,只要用一个变量mem记录当前的,然后看是否比max大即可:

     public int maxSubArray(int[] nums) {
int max = nums[0];
int mem = max;
for (int i = 1; i < nums.length; i++) {
mem = Math.max(mem + nums[i], nums[i]);
max = Math.max(mem, max);
}
return max;
}

扩展:如果我还想知道那个最大子序列的终始位置呢?

     public int[] maxSubArray(int[] nums) {
int n = nums.length;
int[][] dp = new int[n][2];
dp[0][0] = nums[0];
int[] max = {dp[0][0], 0, 0}; for(int i = 1; i < n; i++){
if (dp[i - 1][0] < 0) {
dp[i][0] = nums[i];
dp[i][1] = i;
} else {
dp[i][0] = nums[i] + dp[i-1][0];
dp[i][1] = dp[i-1][1];
} if (max[0] < dp[i][0]) {
max[0] = dp[i][0];
max[1] = dp[i][1];
max[2] = i;
}
} return max;
}

算法复杂度:O(N)

max[] 三个元素分别是 max值、起始位置、终止位置

dp的下标就是终止位置了,所以再给dp加一个维度记录此终止位置对应的起始位置  dp[][]

【注意dp[i][1]的值也要根据 dp[i - 1][0] < 0 的判断而变化】

LeetCode第[53]题(Java):Maximum Subarray的更多相关文章

  1. 【LeetCode每天一题】Maximum Subarray(最大子数组)

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

  2. LeetCode第[18]题(Java):4Sum 标签:Array

    题目难度:Medium 题目: Given an array S of n integers, are there elements a, b, c, and d in S such that a + ...

  3. LeetCode第[1]题(Java):Two Sum 标签:Array

    题目: Given an array of integers, return indices of the two numbers such that they add up to a specifi ...

  4. LeetCode第[46]题(Java):Permutations(求所有全排列) 含扩展——第[47]题Permutations 2

    题目:求所有全排列 难度:Medium 题目内容: Given a collection of distinct integers, return all possible permutations. ...

  5. LeetCode第[1]题(Java):Two Sum (俩数和为目标数的下标)——EASY

    题目: Given an array of integers, return indices of the two numbers such that they add up to a specifi ...

  6. 【LeetCode】最大子阵列 Maximum Subarray(贪婪&分治)

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

  7. LeetCode第[4]题(Java):Median of Two Sorted Arrays 标签:Array

    题目难度:hard There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median ...

  8. 【Leetcode】【Medium】Maximum Subarray

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  9. LeetCode第[29]题(Java):Divide Two Integers

    题目:两整数相除 难度:Medium 题目内容: Given two integers dividend and divisor, divide two integers without using ...

随机推荐

  1. 第三课作业——set类型、sorted set类型的增删改查,redis的事务

    第三课时作业 静哥 by 2016.2.23~2016.3.6   [作业描述] 1.总结什么是set以及什么是sorted set,并完成对set以及sorted set的增删改查(查需要至少4种方 ...

  2. <2014 04 29> c/c++常用库总结

    C 标准库 ============================================================================================== ...

  3. 第13章—数据库连接池(Druid)

    spring boot 系列学习记录:http://www.cnblogs.com/jinxiaohang/p/8111057.html 码云源码地址:https://gitee.com/jinxia ...

  4. linux系统各种日志存储路径和详细介绍

    Linux常见的日志文件详述如下1./var/log/boot.log(自检过程)2./var/log/cron (crontab守护进程crond所派生的子进程的动作)3./var/log/mail ...

  5. 《CNI specification》翻译

    Overview 本文提出了一个通用的基于插件的Linux容器网络解决方案,容器网络接口,CNI.它脱胎于旨在满足大多数rtk网络设计的rtk Networking Proposal. 首先,我们对如 ...

  6. &lt;context-param&gt;与&lt;init-param&gt;的差别与作用

    <context-param>的作用: web.xml的配置中<context-param>配置作用 1. 启动一个WEB项目的时候,容器(如:Tomcat)会去读它的配置文件 ...

  7. HDU2571:命运(简单dp)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=2571 没什么好说的,不过要处理好边界. 代码如下: #include <iostream> # ...

  8. Boost scoped_ptr scoped_array 以及scoped_ptr与std::auto_ptr对比

    boost::scoped_ptr和std::auto_ptr非常类似,是一个简单的智能指针,它能够保证在离开作用域后对象被自动释放.下列代码演示了该指针的基本应用: #include <str ...

  9. Log4Net各参数API

    <?xml version="1.0" encoding="utf-8" ?> <configuration> <configSe ...

  10. HDU - 6311 Cover (欧拉路径)

    题意:有最少用多少条边不重复的路径可以覆盖一个张无向图. 分析:对于一个连通块(单个点除外),如果奇度数点个数为 k,那么至少需要max{k/2,1}  条路径.将奇度数的点两两相连边(虚边),然后先 ...