zoukankan      html  css  js  c++  java
  • 剑指offer30-连续子数组的最大和

    题目描述

    HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)

    思路:

    这个题一开始没有思路,后来看了其他人的代码才自己逐步理解的

    1.因为向量在有负数的情况的下,应该可以看做:正1(包括多个数),负1(也可能包括多个数),正2,负2,正3......

    2.所以将开始的值设为sum,然后一步步往后加,若是sum一直大于0,就一直往下加,若是小于0,就代表遍历了正1,负1,结果是负的,那就放弃前面的正1,负1,因为加上它们肯定会使结果变小(也有人可能认为是正1,负1,正2,负2等等等等,若是这样想的话,那说明正1,负1之后结果是大于0的,加上了正2,负2之后结果才变负了,只能说明正2,负2的结果负的程度更大,同样需要被抛弃)

    3.放弃前面的部分后,再重新开始计算,重新设置sum为放弃部分的后一个值,接着进行上面的进程。

    4.也许有人会说,若是把前面的抛弃了,结果后面的数值更小怎么办?这样的话我们不就把正确答案给扔掉了吗?此时,就是变量max发挥作用的时候了。我们一直保持使max保存迄今为止的最大值。

    class Solution {
    public:
        int FindGreatestSumOfSubArray(vector<int> array) {
            int len = array.size();
            if(len==0)
                return 0;
            int sum = array[0];
            int max = array[0];
            for(int i=1;i<len;i++)
            {
                if(sum>0){
                    //如果sum大于0,就一直加,反正最大值已经存下了,不用怕会丢失
                    sum = sum+array[i]; 
                }
                else{ //如果前面的数的和是负的,就从目前的位置重新开始计
                    sum = array[i];
                }
                if(sum>max){
                    max=sum; //保存前面已经取得的最大值
                }
            }
            return max;
        }
    };
  • 相关阅读:
    uva 11294 Wedding
    uvalive 4452 The Ministers’ Major Mess
    uvalive 3211 Now Or Later
    uvalive 3713 Astronauts
    uvalive 4288 Cat Vs. Dog
    uvalive 3276 The Great Wall Game
    uva 1411 Ants
    uva 11383 Golden Tiger Claw
    uva 11419 SAM I AM
    uvalive 3415 Guardian Of Decency
  • 原文地址:https://www.cnblogs.com/loyolh/p/12347017.html
Copyright © 2011-2022 走看看