关于序列的面试题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 }