连续子数组的最大和


题目描述

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

代码

function FindGreatestSumOfSubArray(array)
{
    // write code here
    //记录每个正数的位置
    let position = [];//用于记录位置
    //最大值在最大负值的左侧或右侧
    let minPosition,min = 0;
    array.forEach((item,index,array)=>
                  {
                    if(item >0) position.push(index);
                    if(item < min){
                        minPosition = index;
                        min = item;
                    }
                  });
    //array的所有元素全为正
    if(min === 0) return array.reduce((pre,cur,index,array)=>{
                                            return pre + cur;
                                      },0);
    //array的所有元素全为负
    if(!position.length) {
            array.sort((pre,cur)=>{
                if(pre < cur) return 1;
                if(pre == cur) return 0;
                if(pre > cur) return -1;
             });
        return array[0];
    }
    let res = [];//记录结果
//根据最小值的位置划分position
    let stop = position.filter((item,index,position)=>{
                                  if (itemminPosition || position[index+1] === undefined))  
                                       return index;
                                      })
    //stop为position的索引的位置
    position.forEach((item,index,position)=>{
                          res.push(array[item]);
                     })
    let left = position.slice(0,stop+1),right = position.slice(stop+1);
   // if(left.length === 1) res.push(array[left[0]]);
    //if(right.length === 1) res.push(array[right[0]]);
    let sum = 0;
    for(let i =0;i{
                if(pre < cur) return 1;
                if(pre == cur) return 0;
                if(pre > cur) return -1;
             })
    return res[0];
    
}

思路:

  • 首先,判断是不是全为正,或全为负 => 返回所有项的和 || 最小的负数。
  • 使用数组position记录每个正数的位置,最大值肯定存在于两个整数之间的所有数的和。
  • 找到最小的值的位置,最大的值肯定为最小的值(即最小的负值)左边的两个正数之间所有数的和 或 右边的两个整数之间的所有数的和。
  • 子向量的长度至少为1,因此我们要把每个正数加入res最终结果数组中。
  • 把position数组根据最小值的位置分为两部分:left 和 right
  • 分别遍历左右两边的所有情况(所有可能的两个正数之间的所有数字的和),并把结果加入到res最终结果数组中。
  • 由于我们把所有的可能值都加入到res数组中了,所以对res结果排序即可得到最终结果。

你可能感兴趣的:(连续子数组的最大和)