关于序列的面试题2------------最大连续子序列和以及积

问题1描述

求取数组中最大连续子序列和,例如给定数组为A={1, 3, -2, 4, -5}, 则最大连续子序列和为6,即1+3+(-2)+ 4 = 6。

 

有O(n3), O(n2), O(nlogn), O(n)各种复杂度不同的解法。这里就说下复杂度最低的解法吧。但是其它复杂度的方法也很重要,因为可以应用到一些变种的问题上。

方法如下:

 1 /*最大连续子序列和*/
 2 #include <stdio.h>
 3 #include <stdlib.h> 
 4 int maxsequence(int a[], int len)
 5 {
 6         int max = a[0];
 7         int sum  = a[0];
 8         for(int i = 1; i < len; i++)
 9         {
10             if(sum <= 0)
11                 sum = a[i];
12             else
13                 sum += a[i];
14             
15             if(sum > max)
16                 max = sum;       
17         }
18         
19         return max;
20 }
21 
22 int main()
23 {
24     int a[10] = {4, -2, 8, -3, -6, 4, -5, 2, -1, 4};
25     printf("%d\n", maxsequence(a, 10));
26     int b[10] = {-4, -2, -8, -3, -6, -4, -5, -2, -1, -4};
27     printf("%d\n", maxsequence(b, 10));
28     
29     system("pause");
30     return 0;
31 }

 

问题2描述

求取数组中最大连续子序列积。

解题思路跟上面的类似

方法如下:

 1 /* 最大连续子序列积 */
 2 int maxproduct(int a[], int len)
 3 {
 4         int max = a[0];
 5         int product  = a[0];
 6         for(int i = 1; i < len; i++)
 7         {
 8             if(product  == 0)
 9                 product  = a[i];
10             else
11                 product  *= a[i];
12             
13             if(product  > max)
14                 max = product;       
15         }
16         product  = a[len-1];
17         for(int i = len - 2 ; i >= 0; i--)
18         {
19             if(product  == 0)
20                 product  = a[i];
21             else
22                 product  *= a[i];
23             
24             if(product > max)
25                 max = product ;       
26         }
27         
28         return max;
29 }
30 int main()
31 {
32     int a[5] = {3, -4, -5, 6, -2};
33     printf("%d\n", maxproduct(a, 5));
34     int b[6] = {2, -3, -4, 0, 6, -2};
35     printf("%d\n", maxproduct(b, 6));
36     system("pause");
37     return 0;
38 }

 

变种问题:

BAT大神在hulu二面的第二道面试题: 求数组绝对值和最小的连续子序列

 

这道题要参考问题1 复杂度O(n2)的方法

可以将这个连续数组用另外一个数组表示,一趟遍历就能构造这个数组

for(i = 1; i <= n; i++)  S[i] = S[i-1] + a[i];

然后这个问题就变成了求数组S中任意两个数之差绝对值最小。

 

下面就简单了, 对数组S进行排序,找相邻最小差值。 复杂度为O(n + nlgn)

代码如下:

 1 int cmp(const void* a, const void* b)
 2 {
 3     return *(int *)a - *(int *)b;
 4 }
 5     
 6 
 7 int minabsolute(int a[], int len)
 8 {
 9         int S[100];
10         S[0] = 0;
11         for(int i = 1; i <= len; i++)
12             S[i] = S[i-1] + a[i-1];
13         
14         qsort(S, len+1, sizeof(int), cmp);
15         int min = S[1] - S[0];
16         for(int i = 2; i < len; i++)
17         {
18             if(S[i] - S[i-1] < min)
19                 min = S[i] - S[i-1];
20         }
21                 
22         return min;
23 }
24 int main()
25 {
26     int a[5] = {3, -4, -5, 9, -2};
27     printf("%d\n", minabsolute(a, 5));
28     int b[6] = {2, -3, -4, 2, 6, -2};
29     printf("%d\n", minabsolute(b, 6));
30     system("pause");
31     return 0;
32 }

 

posted on 2013-05-21 21:38  iamccme  阅读(1377)  评论(1编辑  收藏  举报

导航