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)

 Example

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的更多相关文章

  1. Continuous Subarray Sum II(LintCode)

    Continuous Subarray Sum II   Given an circular integer array (the next element of the last element i ...

  2. [LintCode] Continuous Subarray Sum 连续子数组之和

    Given an integer array, find a continuous subarray where the sum of numbers is the biggest. Your cod ...

  3. Continuous Subarray Sum II

    Description Given an circular integer array (the next element of the last element is the first eleme ...

  4. LintCode "Continuous Subarray Sum"

    A variation to a classical DP: LCS. class Solution { public: /** * @param A an integer array * @retu ...

  5. LintCode 402: Continuous Subarray Sum

    LintCode 402: Continuous Subarray Sum 题目描述 给定一个整数数组,请找出一个连续子数组,使得该子数组的和最大.输出答案时,请分别返回第一个数字和最后一个数字的下标 ...

  6. [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 ...

  7. 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题是存储的当前累加和的 ...

  8. Continuous Subarray Sum

    Given an integer array, find a continuous subarray where the sum of numbers is the biggest. Your cod ...

  9. [LeetCode] Continuous Subarray Sum 连续的子数组之和

    Given a list of non-negative numbers and a target integer k, write a function to check if the array ...

随机推荐

  1. 开机提示grub可咋办啊

    导读 GRUB是多启动规范的实现,它允许用户可以在计算机内同时拥有多个操作系统,并在计算机启动时选择希望运行的操作系统.GRUB可用于选择操作系统分区上的不同内核,也可用于向这些内核传递启动参数. 1 ...

  2. lucene搜索方式(query类型)

    Lucene有多种搜索方式,可以根据需要选择不同的方式. 1.词条搜索(单个关键字查找) 主要对象是TermQuery 调用方式如下: Term term=new Term(字段名,搜索关键字);Qu ...

  3. [POJ1003]Hangover

    [POJ1003]Hangover 试题描述 How far can you make a stack of cards overhang a table? If you have one card, ...

  4. SQL注入--宽字节注入

    PHP测试代码: <?php // 面向对象写法 $id=addslashes($_GET[‘id’]); //获取id并转义预定义字符 // /$id=$_GET[‘id’]; $mysqli ...

  5. Linux 查看网络连接状态

    CLOSED:无连接是活动的或正在进行ESTABLISED:已建立连线的状态:SYN_SENT:发出主动连线 (SYN 标志) 的连线封包:SYN_RECV:接收到一个要求连线的主动连线封包:FIN_ ...

  6. ubuntu 修改保存报错E37:No write since last change(add ! to override)的解决方法

    报错信息如下: E37: No write since last change (add ! to override) 解决办法是: 在修改完后,将命令 :q 改成 :wq 即可.

  7. 局域网所有机器都能连接MySQL数据库的设置命令

    Sql代码: grant all privileges on *.* to root@"%" identified by 'abc' with grant option; flus ...

  8. codeforces A. Strange Addition 解题报告

    题目链接:http://codeforces.com/problemset/problem/305/A 题目意思:给出一个序列,需要从中选择一些数,这些数需要满足:任意的两个数中每一位至少有一个数满足 ...

  9. mysql生成varchar类型主键排序

    用uuid生成20位的主键 SELECT LEFT(REPLACE(UUID(), '-', ''),20) FROM DUAL 另一种方法: 因为数据库中有字母 需要排序的时候去除字母,重新取最大值 ...

  10. VirtualBox 虚拟 Ubuntu 的一些感想

    之前有说过最近在学习Shell,公司及家里的电脑目前都是Windows系统,进行shell学习主要是用一些模拟linux环境的软件,比如banbun.cygwin banbun的功能很强大,集成了oh ...