数组的最大连续子序列

今天在网上看到的这道题目:

一个有N个元素的整型数组arr,有正有负,数组中连续一个或多个元素组成一个子数组,这个数组当然有很多子数组,求子数组之和的最大值。例如:[0,-2,3,5,-1,2]应返回9,[-9,-2,-3,-5,-3]应返回-2。

开始感觉貌似也没有那么难,就直接想循环遍历+动态规划的方法写即可。O(n2)的复杂度,感觉略大,想到上次关于最大子矩阵方法适合的O(n)的方法,感觉这个问题肯定也有这样的解法。在网上搜罗了一下,果真有各种简单的方法,仔细一看,这些方法之间还有关联性,这真的是一种思维方式的不同。

在我以前的想法中,只要能解决问题就行了,但是最近看了很多资料,觉得很多东西都不是自己开始以为的那么简单,很多东西都是需要深入研究学习的,感觉自己真的有很多不懂的地方。只想对自己说:加油,zxh。

废话不多说,代码、详细注释和思维流程都在这里:

 1 //根据动态规划方法,另外设置一个数组subSum[i][j]表示序列i-j的元素的和;
 2 //由题意知道:
 3 //subSum[i][j]=arr[j]  i==j
 4 //subSum[i][j]=subSum[i][j-1]+arr[j]  j<j
 5 //当arr[j]<0时候,subSum[i][j]<subSum[i][j-1]当前的max判断可以省略
 6 int maxSubArr(int arr[],int len){
 7     int sum=INT_MIN,i,j,end;
 8     if(len<=0) return sum;
 9     int **subSum=(int**)malloc(sizeof(int*)*len);
10     for(j=0;j<len;j++)
11     {
12         subSum[j]=(int*)malloc(sizeof(int)*len);
13     }
14
15     for (i=1;i<len+1;i++)//不同长度
16     {
17         for(j=0;j<=len-i;j++)//不同起始下标
18         {
19             end=j+i-1;
20             if(end==j)
21                 subSum[j][end]=arr[end];
22             else
23                 subSum[j][end]=arr[end]+subSum[j][end-1];
24             if(arr[end]>0 )sum=max(sum,subSum[j][end]);
25         }
26     }
27
28     for(j=0;j<len;j++)
29     {
30         free(subSum[j]);
31     }
32     free(subSum);
33
34     return sum;
35 }
36
37 //DP求解方法
38 //可以对数组中最后那一个元素进行分析,arr[len-1],最长子序列跟这个arr[len-1]的关系:
39 //arr[len-1]就是所要求的最长子序列max=arr[len-1]
40 //arr[len-1]是最长子序列的结尾,则有max=arr[len-1]+max[len-2]
41 //arr[len-1]跟最长子序列无关,即max=arr[len-2]
42 //end[i]表示以arr[i]为结尾的所有子序列中和的最大值
43 //all[i]表示从0-i中的序列中和最大的子序列的和
44 //这个只是为了表达清楚,我们其实还可以进一步优化,减少空间复杂度
45 int maxSubArr2(int arr[],int len){
46     int end[30],all[30];
47     int i=0;
48     end[i]=all[i]=arr[0];
49     for (i=1;i<len;i++)
50     {
51         end[i]=max(arr[i],end[i-1]+arr[i]);
52         all[i]=max(end[i],all[i-1]);
53     }
54     return all[i-1];
55 }
56 //maxSubArr2的优化版本
57 int maxSubArr3(int arr[],int len){
58     int end,all;
59     int i=0;
60     end=arr[0];
61     all=arr[0];
62     for (i=1;i<len;i++)
63     {
64         end=max(arr[i],end+arr[i]);
65         all=max(end,all);
66     }
67     return all;
68 }
69 //另一个改进版本
70 //由
71 //end=max(arr[i],end+arr[i]);
72 //all=max(end,all);
73 //这两句,我们可以看到,end是取的arr[i]和arr[i]+end的最大值,那这两个值只有在end<0的情况下才取arr[i]
74 //也就是当end<0时候就重新累加,丢弃掉原来的结果
75 //那么过程就出来了,就是一直累加,每当遇到累加和小于0的时候就从头开始
76 int maxSubArr4(int arr[],int len){
77     int sum=arr[0],maxVal=INT_MIN;
78     int i=0;
79     for (i=1;i<len;i++)
80     {
81         if (sum<0) sum=arr[i];
82         else sum+=arr[i];
83
84         maxVal=max(sum,maxVal);
85     }
86     return maxVal;
87 }

巨人的肩膀:http://www.ahathinking.com/archives/120.html

数组的最大连续子序列,布布扣,bubuko.com

时间: 2024-10-20 20:54:09

数组的最大连续子序列的相关文章

求一个数组中最大连续子序列的和

10.求一个数组中最大连续子序列的和 参考链接:http://blog.csdn.net/butwang/article/details/4691974 思路:如果已经知道在前0~k-1共k个元素中,在最大和为MaxAll[k-1], 怎么求0~k共k+1个元素的MaxAll[k]. 如果前k个元素的最大和子序列包括a[k-1],则很容易知道MaxAll[k] = max(MaxAll[k-1] + a[k], a[k]).那如果前k个元素的最大和子序列不包括a[k-1]呢?在数组后面增加一个元

[LeetCode] 659. Split Array into Consecutive Subsequences 将数组分割成连续子序列

You are given an integer array sorted in ascending order (may contain duplicates), you need to split them into several subsequences, where each subsequences consist of at least 3 consecutive integers. Return whether you can make such a split. Example

[LeetCode] Split Array into Consecutive Subsequences 将数组分割成连续子序列

You are given an integer array sorted in ascending order (may contain duplicates), you need to split them into several subsequences, where each subsequences consist of at least 3 consecutive integers. Return whether you can make such a split. Example

Hdu 5586 sum【最大连续子序列和】

SUM Description There is a number sequence ,you can select a interval [l,r] or not,all the numbers  will become ..After that,the sum of n numbers should be as much as possible.What is the maximum sum? Input There are multiple test cases. First line o

[HDOJ 1003]动态规划法求和最大的连续子序列

题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=1003 Problem Description Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max sum of a sub-sequence. For example, given (6,-1,5,4,-7), the max sum in this sequence is 6 + (-1) + 5

《github一天一道算法题》:分治法求数组最大连续子序列和

看书.思考.写代码! /*************************************** * [email protected] * blog: http://blog.csdn.net/hustyangju * 题目:分治法求数组最大连续子序列和 * 思路:分解成子问题+合并答案 * 时间复杂度:O(n lgn) * 空间复杂度:O(1) ***************************************/ #include <iostream> using nam

LeetCode——数组篇:659. 分割数组为连续子序列

659. 分割数组为连续子序列 输入一个按升序排序的整数数组(可能包含重复数字),你需要将它们分割成几个子序列,其中每个子序列至少包含三个连续整数.返回你是否能做出这样的分割? 示例 1: 输入: [1,2,3,3,4,5] 输出: True 解释: 你可以分割出这样两个连续子序列 : 1, 2, 3 3, 4, 5 示例 2: 输入: [1,2,3,3,4,4,5,5] 输出: True 解释: 你可以分割出这样两个连续子序列 : 1, 2, 3, 4, 5 3, 4, 5 示例 3: 输入:

Leetcode 659.分割数组为连续子序列

分割数组为连续子序列 输入一个按升序排序的整数数组(可能包含重复数字),你需要将它们分割成几个子序列,其中每个子序列至少包含三个连续整数.返回你是否能做出这样的分割? 示例 1: 输入: [1,2,3,3,4,5] 输出: True 解释: 你可以分割出这样两个连续子序列 : 1, 2, 3 3, 4, 5 示例 2: 输入: [1,2,3,3,4,4,5,5] 输出: True 解释: 你可以分割出这样两个连续子序列 : 1, 2, 3, 4, 5 3, 4, 5 示例 3: 输入: [1,2

剑指Offer(Java版)第三十五题:给一个数组,返回它的最大连续子序列的和

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