• [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)

     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(2, 0);
            int n = A.size();
            if(n < 2) 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[0]); for(int i = 1;i < B.size();++i) cumsum.push_back(cumsum[i - 1] + B[i]); int maxVal = B[0], left = 0, right = 0; for(int s = 0;s < n;++s){ //there is no need to start from an negative number, this pruning is useful if(B[s] <= 0) continue; for(int e = s; e < s + n;++e){ int cur = 0; if(s == 0) cur = cumsum[e]; else cur = cumsum[e] - cumsum[s - 1]; if(cur > maxVal){ maxVal = cur; left = s; right = e; } } } result[0] = left%n; result[1] = right%n; return result; }

    解法二:

    进一步分析发现,第二种subarray其实和第一种是相关的。我们可以通过剪掉最小连续子序列得到第二种subarray。这里需要注意当所有数字为负的情况。

    vector<int> continuousSubarraySumII(vector<int>& A) {
            // Write your code here
            vector<int> result(2, 0);
            int n = A.size();
            if(n < 2) return result;
            
            vector<int> posMax(n, 0), posMaxIdx(n, 0), posMin(n, 0), posMinIdx(n, 0);
            posMax[0] = A[0];
            posMin[0] = A[0];
            posMaxIdx[0] = 0;
            posMinIdx[0] = 0;
            int sum = A[0], maxVal = A[0], minVal = A[0], 
                maxL = 0, maxR = 0, minL = 0, minR = 0;
        
            for(int i = 1;i < n;++i){
                sum += A[i];
                //max subArray
                if(posMax[i - 1] > 0){
                    posMax[i] = posMax[i - 1] + A[i];
                    posMaxIdx[i] = posMaxIdx[i - 1];
                }else{
                    posMax[i] = A[i];
                    posMaxIdx[i] = i;
                }
                //min subArray
                if(posMin[i - 1] < 0){
                    posMin[i] = posMin[i - 1] + A[i];
                    posMinIdx[i] = posMinIdx[i - 1];
                }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 == 0 && minR == n - 1)){
                result[0] = maxL;
                result[1] = maxR;
            }else{
                result[0] = minR + 1;
                result[1] = minL - 1;
            }
            
            return result;
        }
  • 相关阅读:
    spring boot 在windows下安装为service(转)
    win7安装Anaconda+TensorFlow+配置PyCharm(转)
    IDEA中Spring boot配置热部署无效问题解决方式(转)
    WEB后台--基于Token的WEB后台登录认证机制(转)
    selenium之使用chrome浏览器测试(附chromedriver与chrome的对应关系表)(转)
    开源巨献:Google最热门60款开源项目(转)
    反射获取一个方法中的参数名(不是类型)(转)
    ELK原理与介绍(转)
    Linux下Redis的安装和部署(转)
    webpack+ES6+less开发环境搭建(转)
  • 原文地址:https://www.cnblogs.com/changchengxiao/p/4763675.html
Copyright © 2020-2023  润新知