[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 ...
随机推荐
- Linux / UNIX create soft link with ln command
How to: Linux / UNIX create soft link with ln command by NIXCRAFT on SEPTEMBER 25, 2007 · 42 COMMENT ...
- java常见异常集锦
1. java.lang.nullpointerexception 这个异常大家肯定都经常遇到,异常的解释是"程序遇上了空指针",简单地说就是调用了未经初始化的对象或者是不存在的对 ...
- Nginx和PHP-FPM的启动/重启脚本 [转发]
Nginx和PHP-FPM的启动/重启脚本 [转发] (2012-07-27 16:07:52) 标签: it 分类: 学习 转载自:http://blog.sina.com.cn/s/blog_53 ...
- 绕过 <?PHP exit('Access Denied'); ?> 限制
绕过 <?PHP exit('Access Denied'); ?> 限制 <?php $shellcode='PD9waHBpbmZvKCk7Pz4';// base64_ ...
- Git SSH Key 生成步骤
it是分布式的代码管理工具,远程的代码管理是基于ssh的,所以要使用远程的git则需要ssh的配置. github的ssh配置如下: 一 . 设置git的user name和email: $ git ...
- window.parent与window.openner 之前的总结
今天总结一下js中几个对象的区别和用法: 1.首先来说说 parent.window与top.window的用法 "window.location.href","loca ...
- Python网络编程(2)——socket模块(2)
目录: 1. 异常 2. 地址族 3. 套接字类型 4. 模块方法 5. Socket对象与实例方法 socket模块提供了Python中的低层网络连接接口,用于操作套接字操作. 异常 socket模 ...
- WebSocket技术
webSocket技术 在html5技术革新中,加入了WebSocket技术 1.webSocket实际是TCP连接 webSocket在最初将发送http连接请求到服务器端, 但是在header中加 ...
- July 28th, Week 31st Thursday, 2016
Time is a bird flying into eternity. 时间是一只永远在飞翔的鸟儿. Time waits for nobody. Vitality shows in not onl ...
- int *p()与int (*p)()的区别
int *p()是返回指针的函数 int (*p)()是指向函数的指针 返回指针的函数: int *a(int x,int y); 有若干个学生的成绩(每个学生有4门课程),要求在用户输入学生序号 ...