首页 > 编程语言 > 详细

30 连续子数组的最大和

时间:2019-06-27 14:55:42      阅读:100      评论:0      收藏:0      [点我收藏+]

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

最开始你可以判断数组是否为空,这个代码在以下4个程序中没有体现

 1 if (array == null || array.length == 0 || (array.length == 1 && array[0] <= 0)) return 0; 

 

方法一:最好的方法 时间复杂度是O(n)

很容易理解,当我们加上一个正数时,和会增加;当我们加上一个负数时,和会减少。如果当前得到的和是个负数,那么这个和在接下来的累加中应该抛弃并重新清零,不然的话这个负数将会减少接下来的和

 1 import java.util.*;
 2 public class Solution {
 3     //求连续数字之和,当和为负值,抛弃.当和为正值,比较其与最大值,如大于,则替换之
 4     public int FindGreatestSumOfSubArray(int[] array) {
 5         int sum = array[0];  //累加求和
 6         int maxSum = array[0];  //记录最大值
 7         for (int i = 1; i < array.length; i++) {
 8             sum = (sum > 0) ? (sum + array[i]) : array[i];
 9             maxSum = Math.max(maxSum, sum);
10         }
11         return max;
12     }
13 }

 

另外初始值如果全都赋值为0的话(5行 6行为0),可以额外考虑下全为负数的情况就可以

技术分享图片
 1 public class FindMaxSumOfSubArray {
 2 
 3     /**
 4      * @param args
 5      */
 6     public static void main(String[] args) {
 7         FindMaxSumOfSubArray f = new FindMaxSumOfSubArray();
 8         int[] arr = { 1, -2, 3, 10, -4, 7, 2, -5 };
 9         System.out.println("MaxSum:" + f.findMaxSum(arr));
10     }
11 
12     public Integer findMaxSum(int[] arr) {
13         int curSum = 0;
14         int maxSum = 0;
15         int len = arr.length;
16 
17         if (arr == null || len == 0) {
18             return null;
19         }
20 
21         for (int i = 0; i < len; i++) {
22             curSum += arr[i];
23             if (curSum < 0) {
24                 curSum = 0;
25             }
26             if (curSum > maxSum) {
27                 maxSum = curSum;
28             }
29         }
30 
31         // all data are negative
32         if (maxSum == 0) {
33             for (int i = 0; i < len; i++) {
34                 if (i == 0) {
35                     maxSum = arr[i];
36                 }
37                 if (arr[i] > maxSum) {
38                     maxSum = arr[i];
39                 }
40             }
41         }
42         return maxSum;
43     }
44 }
View Code

 

 

方法二 暴力求解法

时间复杂度是O(n3)

空间复杂度是O(1)

 1 import java.util.*;
 2 public class Solution {
 3     public int FindGreatestSumOfSubArray(int[] array) {
 4         int len = array.length;
 5         int maxSum =java.lang.Integer.MIN_VALUE;//起初赋值为0,则输入样例全是负数的情况下,代码不通过
 6         for(int i=0;i<len;i++){//每一个可能开始的点
 7             for(int j=i;j<len;j++){//每个可能结束的点
 8                 int temp =0;
 9                 for(int k=i;k<=j;k++) temp+=array[k];//从可能的起始点到可能的终点,求和
10                 if(temp>maxSum) maxSum = temp;
11             }
12         }
13         return maxSum;
14     }
15 }


方法三 在上面个的第9行代码中, 如果求得 i ..... j-1;再进行一次加法,就可以得到i.....j的和,不用再重新加一遍

时间复杂度是O(n2) 少了一个量级

空间复杂度是O(1)

 1 import java.util.*;
 2 public class Solution {
 3     public int FindGreatestSumOfSubArray(int[] array) {
 4         int len = array.length;
 5         int maxSum =java.lang.Integer.MIN_VALUE;//起初赋值为0,则输入样例全是负数的情况下,代码不通过
 6         for(int i=0;i<len;i++){//每一个可能开始的点
 7             int temp =0; //为了改进上一方法的第9行代码,需要提前赋值
 8             for(int j=i;j<len;j++){//每个可能结束的点
 9                 temp+=array[j];
10                 if(temp>maxSum) maxSum = temp;
11             }
12         }
13         return maxSum;
14     }
15 }

 

30 连续子数组的最大和

原文:https://www.cnblogs.com/shareidea94/p/11096723.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!