zoukankan      html  css  js  c++  java
  • 关于序列的面试题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 }
  • 相关阅读:
    bzoj3932 [CQOI2015]任务查询系统
    bzoj1901 Zju2112 Dynamic Rankings
    bzoj3524 [Poi2014]Couriers/2223 [Coci 2009]PATULJCI
    bzoj1529 [POI2005]ska Piggy banks
    bzoj1552 [Cerc2007]robotic sort
    bzoj2208 [Jsoi2010]连通数
    2016NOI冬令营day5
    A1035 Password (20)(20 分)
    1048 数字加密(20 分)
    福尔摩斯的约会
  • 原文地址:https://www.cnblogs.com/iamccme/p/3091641.html
Copyright © 2011-2022 走看看