剑指offer - 面试题42: 连续子数组的最大和 - C++

今天同学说腾讯面试考到这道了,知道自己做过,但就是想不起来怎么做,很惶恐,很无奈。想了很久,去上网查了一下思路:如果左边的和小于0就舍弃。

靠着这个提示和自己的记忆,敲出如下

class Solution {
public:
    int FindGreatestSumOfSubArray(vector<int> array) {
        int length = array.size();
        if(length == 0) return 0;
         
        int left = 0;
        int right = 0;
        int maxSum = array[0];
        int currentSum = array[0];
        while(right < length-1) {
            right++;
            if(currentSum < 0) {
                left = right;
                currentSum = array[left];
            } else {
                currentSum += array[right];
            }
            if(currentSum > maxSum) {
                maxSum = currentSum;
            }
             
        }
        return maxSum;
    }
};

写完之后去看书上,发现只有一个for 循环,循环变量表示子数组右侧,于是改自己的代码,改错两次。其中一次没注意循环变量初始值,改掉之后发现循环变量从0开始的话涉及到currentSum和maxSum不能单纯地赋值为0,因为天知道这个数组会不会全是负数。有两种办法:currentSum和maxSum赋值为最小负数0x80000000,并不知道为什么;或者循环变量从1开始。改对之后如下

class Solution {
public:
    int FindGreatestSumOfSubArray(vector<int> array) {
        int length = array.size();
        if(length == 0) return 0;

        int maxSum = array[0];
        int currentSum = array[0];
        for(int right=1; right<length; right++) {
            if(currentSum < 0) {
                currentSum = array[right];
            } else {
                currentSum += array[right];
            }
            if(currentSum > maxSum) {
                maxSum = currentSum;
            }
        }
        return maxSum;
    }
};

其实上一种方法也不是一无所长,假如要返回子数组的始末坐标....

书上第二种方法是动态规划,f(i)是以i结尾的子数组的最大和。f(i)和f(i-1)的关系明确。最后写出的代码和上一种思路一样~

希望这道题我真的掌握了哦~

猜你喜欢

转载自blog.csdn.net/L_bic/article/details/88820982