lintcode:最大子数组II
题目
最大子数组 II
给定一个整数数组,找出两个不重叠子数组使得它们的和最大。
每个子数组的数字在数组中的位置应该是连续的。
返回最大的和。
给出数组[1, 3, -1, 2, -1, 2],这两个子数组分别为[1, 3]和[2, -1, 2]或者[1, 3, -1, 2]和[2],它们的最大和都是7
子数组最少包含一个数
要求时间复杂度为O(n)
解题
最大子数组I 这个题目是求一个数组中一个最大子数组的和,而本题目是求数组中的前两个最大子数组的和。然后就想到定义两个数组:left 、right 。
left[i] 表示从左开始到第i个值,并且包括第i个值的最大数组值
right[i]表示从size-1开始到第i个值,并且包括第i个值的最大数组
下面只需要找出两个数组和的最大值,并且两个数组的节点值不能有交集,这里需要遍历所有可能,时间复杂度是O(N2)
public class Solution {
/**
* @param nums: A list of integers
* @return: An integer denotes the sum of max two non-overlapping subarrays
*/
public int maxTwoSubArrays(ArrayList<Integer> nums) {
// write your code
int size = nums.size();
if(nums==null || size ==0)
return 0;
int[] left = new int[size];
int[] right = new int[size];
left[0] = nums.get(0);
right[size-1] = nums.get(size-1);
for(int i=1;i<size;i++){
left[i] = Math.max(left[i-1] + nums.get(i),nums.get(i));
}
for(int j=size-2;j>=0 ;j--){
right[j] = Math.max(right[j+1] + nums.get(j),nums.get(j));
}
int max = Integer.MIN_VALUE;
for(int i=0;i<size;i++){
for(int j=size-1;j>i ; j--){
int tmp = left[i] + right[j];
max = Math.max(max,tmp);
}
}
return max;
}
}
Java Code
只求出左到右某个位置的最大子数组,再增加标志位来表示该位置是否是新的子数组的起始位置,然而后面不知道怎么搞了。
参考博客 上面定义的left数组 还是right数组中的值 是包含当前元素的最大值是 局部最大值
在上面博客中定义了全局最大值,这样定义的数组就是一个非降序的数组
数组left ,left[i] 表示从0 到i 这个区间内元素的最大值
同样可以求从i 到 size-1 这个区间的最大值
上面两个值之和的最大值就是答案了
public class Solution {
/**
* @param nums: A list of integers
* @return: An integer denotes the sum of max two non-overlapping subarrays
*/
public int maxTwoSubArrays(ArrayList<Integer> nums) {
// write your code
int size = nums.size();
if(nums==null || size ==0)
return 0;
int max = Integer.MIN_VALUE;
int left[] = new int[size];
int localMax = 0;
int globalMax = Integer.MIN_VALUE;
for(int i=0;i< size;i++){
localMax = Math.max(localMax+nums.get(i) , nums.get(i));
globalMax = Math.max(localMax,globalMax);
left[i] = globalMax;
}
localMax = 0;
globalMax = Integer.MIN_VALUE;
for(int i = size -1;i>=0;i--){
if(i< size -1)
max = Math.max(max,globalMax+left[i]);
localMax = Math.max(localMax + nums.get(i),nums.get(i));
globalMax = Math.max(localMax,globalMax);
}
return max;
}
}
Java Code
上面的第二个for循环也就是求i 到size -1 区间内的全局最大值,然后就想到可以再定义一个数组
right right[i] 表示从i 到 size -1这个区间的最大
下面只需要根据这个两个数组求出最大值的和就好了
max = Math.max(left[i] + right[i+1],max)
再说明下:
left[i] 表示从0 到i 这个区间的最大值
right[i+1] 表示从 i + 1 都 size-1 这个区间的最大值
显然上面的和的最大值就是答案了
public class Solution {
/**
* @param nums: A list of integers
* @return: An integer denotes the sum of max two non-overlapping subarrays
*/
public int maxTwoSubArrays(ArrayList<Integer> nums) {
// write your code
int size = nums.size();
if(nums==null || size ==0)
return 0;
int max = Integer.MIN_VALUE;
int left[] = new int[size];
int localMax = 0;
int globalMax = Integer.MIN_VALUE;
for(int i=0;i< size;i++){
localMax = Math.max(localMax+nums.get(i) , nums.get(i));
globalMax = Math.max(localMax,globalMax);
left[i] = globalMax;
}
localMax = 0;
globalMax = Integer.MIN_VALUE;
int right[] = new int[size];
for(int i = size -1;i>=0;i--){
localMax = Math.max(localMax + nums.get(i),nums.get(i));
globalMax = Math.max(localMax,globalMax);
right[i] = globalMax;
}
for(int i=0;i< size-1;i++){
max = Math.max(left[i] + right[i+1],max);
}
return max;
}
}
Java Code
Python
class Solution:
"""
@param nums: A list of integers
@return: An integer denotes the sum of max two non-overlapping subarrays
"""
def maxTwoSubArrays(self, nums):
# write your code here
if not nums:
return 0 size = len(nums)
left, right = [0 for i in range(size)], [0 for i in range(size)]
MAX, localMax, globalMax = -sys.maxint - 1, 0, -sys.maxint-1
for i in range(size):
localMax = max(localMax+ nums[i],nums[i])
globalMax = max(localMax,globalMax)
left[i] = globalMax
localMax = 0
globalMax = -sys.maxint - 1
for j in range(size-1,-1,-1):
localMax = max(localMax + nums[j],nums[j])
globalMax = max(localMax,globalMax)
right[j] = globalMax
for i in range(size-1):
MAX = max(left[i] + right[i+1],MAX)
return MAX
Python Code
这里为什么求了最小值,表示不理解
lintcode:最大子数组II的更多相关文章
- lintcode-42-最大子数组 II
42-最大子数组 II 给定一个整数数组,找出两个 不重叠 子数组使得它们的和最大. 每个子数组的数字在数组中的位置应该是连续的. 返回最大的和. 注意事项 子数组最少包含一个数 样例 给出数组 [1 ...
- lintcode :最大子数组
题目: 最大子数组 给定一个整数数组,找到一个具有最大和的子数组,返回其最大和. 样例 给出数组[−2,2,−3,4,−1,2,1,−5,3],符合要求的子数组为[4,−1,2,1],其最大和为6 ...
- lintcode:合并排序数组 II
题目: 合并排序数组 II 合并两个排序的整数数组A和B变成一个新的数组. 样例 给出A = [1, 2, 3, empty, empty] B = [4,5] 合并之后A将变成[1,2,3,4,5] ...
- lintcode 最大子数组III
题目描述 给定一个整数数组和一个整数 k,找出 k 个不重叠子数组使得它们的和最大.每个子数组的数字在数组中的位置应该是连续的. 返回最大的和. 注意事项 子数组最少包含一个数 样例 给出数组 [-1 ...
- LintCode——合并排序数组II
描述:合并两个排序的整数数组A和B变成一个新的数组 样例:给出A=[1,2,3,4],B=[2,4,5,6],返回 [1,2,2,3,4,4,5,6] 1.Python:先将数组B加到数组A之后,然后 ...
- [LintCode] 合并排序数组II
class Solution { public: /** * @param A: sorted integer array A which has m elements, * but size of ...
- 最大子数组(I, II, III,IV,V)和最大子数组乘积 (动态规划)
I 找一个连续最大子数组,sum加到nums[i], 如果前面子数组和<0则舍去,从头开始. class Solution { public: /** * @param nums: A list ...
- lintcode 中等题:搜索旋转排序数组II
题目 搜索旋转排序数组 II 跟进“搜索旋转排序数组”,假如有重复元素又将如何? 是否会影响运行时间复杂度? 如何影响? 为何会影响? 写出一个函数判断给定的目标值是否出现在数组中. 样例 给出[3, ...
- lintcode:最大子数组差
题目 最大子数组差 给定一个整数数组,找出两个不重叠的子数组A和B,使两个子数组和的差的绝对值|SUM(A) - SUM(B)|最大. 返回这个最大的差值. 样例 给出数组[1, 2, -3, 1], ...
随机推荐
- MAC上 nodejs express 安装
最近在MAC上搭建 nodejs环境以及安装 express 框架,遇到了一些问题,不过最后总算还是安装成功了,下面是操作步骤 1.node js 安装 访问nodejs官网进入下载mac上的安装包 ...
- ajax 设置Access-Control-Allow-Origin实现跨域访问
ajax跨域访问是一个老问题了,解决方法很多,比较常用的是JSONP方法,JSONP方法是一种非官方方法,而且这种方法只支持GET方式,不如POST方式安全. 即使使用jquery的jsonp方法,t ...
- ASP.NET MVC4学习笔记之总体概述
断断续续使用ASP.NET MVC框架也有一年多了,也算积累了一些经验,唉,一直想写一些笔记好好总结一下,人太懒不想动笔,今天终于决定开始.希望自己能坚持下去. 这篇文章大体介绍ASP.NET MVC ...
- python: 生成guid
其实经常需要生成一个guid,在各种场合使用...也简单写个小脚本实现吧. 实现下来发现速度比较慢... import uuid import sys def show_ver(): print 'g ...
- 存储映射IO
mmap 将文件映射到内存, 对这块内存的修改会自动同步到相应的文件中 void *mmap(void *addr, size_t len, int prot, int flag, int fd, o ...
- 【Nhibernate】入门 踩雷篇
总结(喜欢写在前面,记性不好老忘记解决问题时的思路): 使用框架一般不会完整的看文档,直接上来就搞,踩雷是必须的,重要的是遇到雷的时候要快速变换思路,是不是姿势不对(文件位置不对) 提高解决问题的速度 ...
- 序列化form表单内容为json对象
SourceCode: ; (function ($) { $.fn.extend({ serializeJson: function () { var json = {}; $(this.seria ...
- 还原没有日志文件的SQL数据库
1.执行命令示例: EXEC sys.sp_attach_db @dbname = 'AdventrueWorks2012_Data', @filename1 = N'C:\Program F ...
- JAVA算术运算符、关系运算符和位运算符
算术运算符 1.java的算数运算符包括+(加).-(减).*(乘)./(除).%(取余),在运算过程中出现的隐式转换原则和C语言一样:2. 高位数据向低位数据转化要使用强制转化: 关系运算符 1.j ...
- 微软职位内部推荐-Principal Dev Manager
微软近期Open的职位: Title: Principal Dev Manager Location: Beijing The R&D of Shared Data Platform at S ...