[LintCode] Continuous Subarray Sum II
Given an integer array, find a continuous rotate subarray where the sum of numbers is the biggest. Your code should return the index of the first number and the index of the last number. (If their are duplicate answer, return anyone. The answer can be rorate array or non- rorate array)
Give [3, 1, -100, -3, 4], return [4,1].
分析:
此题是Continuous Subarray Sum的升级版本。对于给定序列A, Continuous Subarray Sum中,子序列为A{i -> j}, 要求 0 <= i <= j < size(A),此为经典动态规划问题。在这里,子序列除了有之前的形式外,还允许rotate subarray,即子序列允许从尾部延续到头部,形式为A{0 -> i, j -> size(A) - 1}。
解法一:
因为允许尾部到头部形成子序列。通常的想法是把数据copy一份连到尾部。此时我们可以用Continous Subarray Sum的解法来做。但是有一点区别,我们的子序列长度不能超过size(A)。因此,我们依然可以用动态规划来做,不过需要考虑到序列的长度。为了实现简便,下面给出一个O(N^2) 非动态规划的解法,利用了累计数列和条件剪枝。不过最后三个数据还是会超时。
vector<int> continuousSubarraySumII(vector<int>& A) {
// Write your code here
vector<int> result(, );
int n = A.size();
if(n < ) return result;
//duplicate array
vector<int> B(A);
B.insert(B.end(), A.begin(), A.end());
//cumsum can help to calculate the sum from B(i) to B(j) with O(1) time
vector<int> cumsum;
cumsum.push_back(B[]);
for(int i = ;i < B.size();++i)
cumsum.push_back(cumsum[i - ] + B[i]);
int maxVal = B[], left = , right = ;
for(int s = ;s < n;++s){
//there is no need to start from an negative number, this pruning is useful
if(B[s] <= ) continue;
for(int e = s; e < s + n;++e){
int cur = ;
if(s == ) cur = cumsum[e];
else cur = cumsum[e] - cumsum[s - ];
if(cur > maxVal){
maxVal = cur;
left = s;
right = e;
}
}
}
result[] = left%n;
result[] = right%n;
return result;
}
解法二:
进一步分析发现,第二种subarray其实和第一种是相关的。我们可以通过剪掉最小连续子序列得到第二种subarray。这里需要注意当所有数字为负的情况。
vector<int> continuousSubarraySumII(vector<int>& A) {
// Write your code here
vector<int> result(, );
int n = A.size();
if(n < ) return result;
vector<int> posMax(n, ), posMaxIdx(n, ), posMin(n, ), posMinIdx(n, );
posMax[] = A[];
posMin[] = A[];
posMaxIdx[] = ;
posMinIdx[] = ;
int sum = A[], maxVal = A[], minVal = A[],
maxL = , maxR = , minL = , minR = ;
for(int i = ;i < n;++i){
sum += A[i];
//max subArray
if(posMax[i - ] > ){
posMax[i] = posMax[i - ] + A[i];
posMaxIdx[i] = posMaxIdx[i - ];
}else{
posMax[i] = A[i];
posMaxIdx[i] = i;
}
//min subArray
if(posMin[i - ] < ){
posMin[i] = posMin[i - ] + A[i];
posMinIdx[i] = posMinIdx[i - ];
}else{
posMin[i] = A[i];
posMinIdx[i] = i;
}
if(posMax[i] > maxVal){
maxVal = posMax[i];
maxL = posMaxIdx[i];
maxR = i;
}
if(posMin[i] < minVal){
minVal = posMin[i];
minL = posMinIdx[i];
minR = i;
}
}
int val = sum - minVal;
if(val <= maxVal || (minL == && minR == n - )){
result[] = maxL;
result[] = maxR;
}else{
result[] = minR + ;
result[] = minL - ;
}
return result;
}
[LintCode] Continuous Subarray Sum II的更多相关文章
- Continuous Subarray Sum II(LintCode)
Continuous Subarray Sum II Given an circular integer array (the next element of the last element i ...
- [LintCode] Continuous Subarray Sum 连续子数组之和
Given an integer array, find a continuous subarray where the sum of numbers is the biggest. Your cod ...
- Continuous Subarray Sum II
Description Given an circular integer array (the next element of the last element is the first eleme ...
- LintCode "Continuous Subarray Sum"
A variation to a classical DP: LCS. class Solution { public: /** * @param A an integer array * @retu ...
- LintCode 402: Continuous Subarray Sum
LintCode 402: Continuous Subarray Sum 题目描述 给定一个整数数组,请找出一个连续子数组,使得该子数组的和最大.输出答案时,请分别返回第一个数字和最后一个数字的下标 ...
- [LintCode] Subarray Sum & Subarray Sum II
Subarray Sum Given an integer array, find a subarray where the sum of numbers is zero. Your code sho ...
- leetcode 560. Subarray Sum Equals K 、523. Continuous Subarray Sum、 325.Maximum Size Subarray Sum Equals k(lintcode 911)
整体上3个题都是求subarray,都是同一个思想,通过累加,然后判断和目标k值之间的关系,然后查看之前子数组的累加和. map的存储:560题是存储的当前的累加和与个数 561题是存储的当前累加和的 ...
- Continuous Subarray Sum
Given an integer array, find a continuous subarray where the sum of numbers is the biggest. Your cod ...
- [LeetCode] Continuous Subarray Sum 连续的子数组之和
Given a list of non-negative numbers and a target integer k, write a function to check if the array ...
随机推荐
- Brackets(区间dp)
Brackets Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 3624 Accepted: 1879 Descript ...
- Java中的向上转型和向下转型
首先要明白一点向上转型和向下转型他们都是建立在继承的基础上. 一.向上转型 子类到父类的转换通常称作向上转型,通俗的说就是定义父类对象指向子类对象. 下面通过一个例子来深入理解向上转型. //定义一个 ...
- 对原型prototype的详解
刚开始接触对象原型时大脑就开始起义了,脑子就转不灵清了.就感觉怎么着这个概念就是灌输不进去,俗称断路.后面找了很多资料,最主要的还是要借助于<JavaScript语言精髓>这本书,让我对这 ...
- PHP中通过加号合并数组
通常,我们合并多个数组用的是array_merge()函数,其实,PHP手册中关于数组操作符的介绍给了我们更简单的方法,那就是"+"号,看看下面的例子就明白了(详细了解) 代码: ...
- linux 系统下查看raid信息,以及磁盘信息
有时想知道服务器上有几块磁盘,如果没有做raid,则可以简单使用fdisk -l 就可以看到. 但是做了raid呢,这样就看不出来了.那么如何查看服务器上做了raid? 软件raid:只能通过Lin ...
- 【云计算】基于Ansible的自动部署平台化思路
目标: 1.自动化—支持命令行.webui.api调用 2.支持基础命令.脚本.复杂任务编排.满足生产环境各类模块自动化部署需求 3.满足生产环境(开发.测试.线上)性能.可靠性.安全性要求 4.流程 ...
- order by 指定顺序 mysql
LOCATE(substr,str), LOCATE(substr,str,pos) 第一个语法返回字符串str第一次出现的子串SUBSTR的位置.第二个语法返回第一次出现在字符串str的子串SUBS ...
- Word Pattern | & II
Word Pattern | Given a pattern and a string str, find if str follows the same pattern. Examples: pat ...
- STM32canopen调试
问题1:用usbcan监测不到can口的报文 属于接线问题 CANopen程序总使用的是can1 对应的接下口在J1的1和2口,而其接口排序是从外向里排序,故最外面的为1号接口,由于接线时,按照左边的 ...
- jquery给height拼接动态变量
var sizeLength = "${list.size()}"; if(sizeLength==''){ sizeLength=0; } sizeLength=400*size ...