LintCode 最大子数组(3种方法)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_30440627/article/details/54924737

给定一个整数数组,找到一个具有最大和的子数组,返回其最大和。

样例

给出数组[−2,2,−3,4,−1,2,1,−5,3],符合要求的子数组为[4,−1,2,1],其最大和为6


方法一 :暴力枚举,时间复杂度O(n3)

1、找出子数组的最左端点     for i<-1 to n

2、找出子数组的最右端点     for j<-i  to n

3、求和,找出最大值            sum = a[i] +……+a[j];  ans = max(ans, sum)

class Solution {
public:
    /**
     * @param nums: A list of integers
     * @return: A integer indicate the sum of max subarray
     */
    int maxSubArray(vector<int> nums) {
        // write your code here
        int n = nums.size();
        int ans = -1000000;      //因为求最大值,所以给结果初始化一个很小的数
        for(int i=0; i<n; i++)
        {
            for(int j=i; j<n; j++)
            {
                int sum = 0;
                for(int k=i; k<=j; k++)
                {
                    sum += nums[k];
                }
                if(sum > ans)
                {
                    ans = sum;
                }
            }
        }
        return ans;
    }
};

但是很明显时间复杂度太大,只是作为一种最基础的方法,在此基础上再考虑优化方法。

慢在哪里?找冗余操作,执行次数最多的操作。求和操作被执行了很多次,有很多是重复计算的。


方法二 :优化枚举,时间复杂度O(n2)

左端点相同的子数组,随着长度的增加,排在前面的元素被不断重复相加。如果我们记录下之前的求和结果,

就不需要对前面的元素再进行计算,比方法一少了一重循环。

class Solution {
public:
    /**
     * @param nums: A list of integers
     * @return: A integer indicate the sum of max subarray
     */
    int maxSubArray(vector<int> nums) {
        // write your code here
        int n = nums.size();
        int ans = -1000000;
        for(int i=0; i<n; i++)
        {
            int sum = 0;
            for(int j=i; j<n; j++)
            {
                sum += nums[j];
                if(sum > ans)
                {
                    ans = sum;
                }
            }
        }
        return ans;
    }
};
显然O(n2)的复杂度还是不令人满意。继续寻找冗余操作。

如果子串A的和是负数,而子串B包含子串A,那B则不需要进行计算。这样就省去了一些计算步骤。


方法三:贪心法,复杂度O(n)

将子串和为负数的子串丢掉,只留和为正的子串。

class Solution {
public:
    /**
     * @param nums: A list of integers
     * @return: A integer indicate the sum of max subarray
     */
    int maxSubArray(vector<int> nums) {
        // write your code here
        int n = nums.size();
        int ans = -1000000;
        int sum = 0;
        for(int i=0; i<n; i++)
        {
            sum += nums[i];
            if(sum > ans)
            {
                ans = sum;
            }
            if(sum < 0)
            {
                sum = 0;   //子串和为负数,丢掉
            }
        }
        return ans;
    }
};





猜你喜欢

转载自blog.csdn.net/sinat_30440627/article/details/54924737
今日推荐