今天同学说腾讯面试考到这道了,知道自己做过,但就是想不起来怎么做,很惶恐,很无奈。想了很久,去上网查了一下思路:如果左边的和小于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)的关系明确。最后写出的代码和上一种思路一样~
希望这道题我真的掌握了哦~