最近由于碰到了一道题,最大子列和的问题,做的不是太好,于是就翻出来重新看了一遍,用js实现了一下。其实有四种解法,但是那个分而治之的楼主还不太明白,不敢乱说。就只在这里写了3种。
算法1:暴力求解,就是找出所有组合 ,然后找到最大的那个。
var a=[-2,11,-4,13,-5,-2]
function Maxsum(arr){
var thissum=0;
var maxsum=0;
var n=a.length;
for(var i=0;i<n;i++){ //i 是子列左端的位置
for(var j=i;j<n;j++){ //j是子列右端的位置
thissum=0; //记录的从i到j的子列和 一定要在这里初始化为0喔,因为这里记录的是每个组合的子列求和的开始位置
for(var k=i;k<j;k++){
thissum+=arr[k];
}
if(thissum>maxsum){ //判断条件 如果当前和大于最大值 那么最大值就等于当前和
maxsum=thissum;
}
}
}
console.log(maxsum) //循环结束 打印最大子列和
}
Maxsum(a);
算法一虽然解决了问题 但是时间复杂度是三层for循环,而且我们发现k循环那层是没有必要的,因为算法一在求解子列和的时候都是从头开始的,其实我们可以在i相同的基础上,每次加j,就可以得到子列和,于是就有了算法2
算法2:
var a=[-2,11,-4,13,-5,-2]
function Maxsum(arr){
var thissum=0;
var maxsum=0;
var n=a.length;
for(var i=0;i<n;i++){ //i 是子列左端的位置
thissum=0;
for(var j=i;j<n;j++){ //j是子列右端的位置
thissum+=a[j];
//对于相同的i不同的j,只要在j-1次循环的基础上累加1项即可
if(thissum>maxsum){ //判断条件 如果当前和大于最大值 那么最大值就等于当前和
maxsum=thissum;
}
}
}
console.log(maxsum) //循环结束 打印最大子列和
}
Maxsum(a);
算法3:在线处理
这个算法的时间复杂度低,但是缺点是可靠度也低
var a=[-2,11,-4,13,-5,-2]
function maxSum(arr){
var thissum=0;
var maxsum=0;
var n=a.length;
for(var i=0;i<n;i++){
// 向右累加
thissum+=arr[i];
//如果当前和大于最大值 更新最大值
if(thissum>maxsum){
maxsum=thissum;
}
//如果当前和小于0,则不可能使得后面的部分和增大,所以抛弃
else if(thissum<0){
thissum=0;
}
}
console.log(maxsum)
}
maxSum(a);
最近做剑指offer,遇到了类似的题,发现了新的解法,现将其补充在这里。这个方法比前三种效率更高。
function FindGreatestSumOfSubArray(array)
{
if (array.length === 0) return 0;
var max = array[0]; //将array[0]赋值给max
var temp = array[0]; //将array[0]赋值给temp
for (var i = 1; i < array.length; i++) {
//如果temp>0,那么对于求和是有帮助的 否则对于求和没有帮助 那么就等于数组中的下一个数
if(temp>0){
temp+=array[i];
}
else{
temp=array[i];
}
//如果最大值大于temp 则最大值不变
if(max>temp){
max=max;
}
//如果最大值小于temp 则更新最大值
else {
max=temp;
}
}
console.log(max)
return max
}
array=[2,8,1,5,9];
FindGreatestSumOfSubArray(array)