zoukankan      html  css  js  c++  java
  • 【数组】Maximum Subarray

    题目:

    Find the contiguous subarray within an array (containing at least one number) which has the largest sum.

    For example, given the array [−2,1,−3,4,−1,2,1,−5,4],
    the contiguous subarray [4,−1,2,1] has the largest sum = 6.

    click to show more practice.

    More practice:

    If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.

    思路:

    方法一:动态规划, 数组为vec[],设dp[i] 是以vec[i]结尾的子数组的最大和,对于元素vec[i+1], 它有两种选择:a、vec[i+1]接着前面的子数组构成最大和,b、vec[i+1]自己单独构成子数组。则dp[i+1] = max{dp[i]+vec[i+1],  vec[i+1]}

    附加:记录左右节点位置

    /**
     * @param {number[]} nums
     * @return {number}
     */
    var maxSubArray = function(nums) {
        var sum=0,maxsum=-2147483648,begin=0;
        for(var i=0,len=nums.length;i<len;i++){
            if(sum>=0){
                sum=sum+nums[i];
            }else{
                sum=nums[i];
                begin=i;
            }
            
            if(maxsum<sum){
                maxsum=sum;
                left=begin;
                right=i;
            }
        }
        
        return maxsum;
    };

    方法二

    最简单的就是穷举所有的子数组,然后求和,复杂度是O(n^3)

    int maxSum1(vector<int>&vec, int &left, int &right)
    {
        int maxsum = INT_MIN, sum = 0;
        for(int i = 0; i < vec.size(); i++)
            for(int k = i; k < vec.size(); k++)
            {
                sum = 0;
                for(int j = i; j <= k; j++)
                    sum += vec[j];
                if(sum > maxsum)
                {
                    maxsum = sum;
                    left = i;
                    right = k;
                }
            }
        return maxsum;
    }
     

    算法三:

    上面代码第三重循环做了很多的重复工作,稍稍改进如下,复杂度为O(n^2)

    int maxSum2(vector<int>&vec, int &left, int &right)
    {
        int maxsum = INT_MIN, sum = 0;
        for(int i = 0; i < vec.size(); i++)
        {
            sum = 0;
            for(int k = i; k < vec.size(); k++)
            {
                sum += vec[k];
                if(sum > maxsum)
                {
                    maxsum = sum;
                    left = i;
                    right = k;
                }
            }
        }
        return maxsum;
    }
    算法四:
    分治法, 下面贴上编程之美的解释, 复杂度为O(nlogn)

    image

    image

    //求数组vec【start,end】的最大子数组和,最大子数组边界为[left,right]
    int maxSum3(vector<int>&vec, const int start, const int end, int &left, int &right)
    {
        if(start == end)
        {
            left = start;
            right = left;
            return vec[start];
        }
        int middle = start + ((end - start)>>1);
        int lleft, lright, rleft, rright;
        int maxLeft = maxSum3(vec, start, middle, lleft, lright);//左半部分最大和
        int maxRight = maxSum3(vec, middle+1, end, rleft, rright);//右半部分最大和
        int maxLeftBoeder = vec[middle], maxRightBorder = vec[middle+1], mleft = middle, mright = middle+1;
        int tmp = vec[middle];
        for(int i = middle-1; i >= start; i--)
        {
            tmp += vec[i];
            if(tmp > maxLeftBoeder)
            {
                maxLeftBoeder = tmp;
                mleft = i;
            }
        }
        tmp = vec[middle+1];
        for(int i = middle+2; i <= end; i++)
        {
            tmp += vec[i];
            if(tmp > maxRightBorder)
            {
                maxRightBorder = tmp;
                mright = i;
            }
        }
        int res = max(max(maxLeft, maxRight), maxLeftBoeder+maxRightBorder);
        if(res == maxLeft)
        {
            left = lleft;
            right = lright;
        }
        else if(res == maxLeftBoeder+maxRightBorder)
        {
            left = mleft;
            right = mright;
        }
        else
        {
            left = rleft;
            right = rright;
        }
        return res;
    }
  • 相关阅读:
    禅道,导出选中的用例
    chrome 历史版本下载地址
    在QT中添加zeromq DLL库
    在QT中添加zeromq DLL库
    在QT中添加zeromq库,zeromq的下载编译
    工控软件dll劫持漏洞分析
    [转载]Impost3r:一款针对Linux的密码提取工具
    0MQ绑定Delphi版-说明
    通过Maven导出war包时报错:Failed to execute goal org.apache.maven.plugins:maven-war-plugin:2.2:war (default-war) on project Ocr: Error assembling WAR: webxml
    价值投资必须掌握的几个指标zz
  • 原文地址:https://www.cnblogs.com/shytong/p/5115781.html
Copyright © 2011-2022 走看看