免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: davycu
打印 上一主题 下一主题

[算法] 迅雷笔试题 [复制链接]

论坛徽章:
0
41 [报告]
发表于 2010-09-16 09:18 |只看该作者
最大序列肯定是以正数开始 正数结束。如果全是负数就求最大值 先从左边遍历找出第一个正数 同时记录最大值
如果没有正数 那负数最大值就是所求

论坛徽章:
0
42 [报告]
发表于 2010-09-16 09:37 |只看该作者
昨天那个有点问题

论坛徽章:
0
43 [报告]
发表于 2010-09-16 09:38 |只看该作者
void cpu_utility(int *a, int n)
{
        int begin,end,max,sbegin;
        int sum = 0;
        int i = 0;

        max = a[0];
        sbegin = end = 0;
        while (i < n && a[i] < 0)
        {
                if (a[i] > max)
                {
                        max = a[i];
                        sbegin = i;
                        end = i;
                }
                i++;
        }
       
        begin = i;
        if (begin != n)
        {
                for (i = begin;i < n;i++)
                {
                        sum += a[i];
                        if (sum < 0)
                        {
                                sbegin = i+1;
                                sum = 0;
                        }

                        if (sum > max)
                        {
                                max = sum;
                                end = i;
                        }
                }
        }
        begin = sbegin;
        printf("max: %d,begin: %d,end: %d\n",max,begin+1,end+1);
}

论坛徽章:
0
44 [报告]
发表于 2010-09-16 10:10 |只看该作者
本帖最后由 petery87 于 2010-09-16 11:07 编辑

回复 37# shangat

初始化条件改一下,max初始化为数组第一个元素,len初始化为1.
这样以下4种情况都可以处理了。
   0. a[] = { -8, -3, -4, -7, -9, -6, -8, -5, -7}
   1. a[] = { -3, -2, 7, -9, -1}
   2. a[] = { 0, -2, -6, -6, -9, -4, -2, -1, -3}
   3. a[] = { 0, -2, -6, -6, -9, 0, -2, -1, -3}

  1. #include <stdio.h>

  2. int main()
  3. {
  4.     int a[] = { -8, -3, -4, -7, -9, -6, -8, -5, -7};
  5.     //int a[] = {0, -1, -2, -3, 0, -4, -8};
  6.     //int a[] = {1, 1, -3, -3, -4, 3, 4, -8, 2, 3};
  7.     //int a[] = {9, -12, 120, 8, -20, 100, 30, -89, 20};
  8.     int start;          /* 子数组开始下标 */
  9.     int temp_start;     /* 临时计数的数组开始下标 */
  10.     int len;            /* 子数组长度 */
  11.     int sum;            /* 临时计数 */
  12.     int max;            /* 子数组的和 */

  13.     int i;
  14.     start = sum = temp_start = 0;
  15.     len = 1;
  16.     max = a[0];

  17.     for(i = 0; i < sizeof(a)/sizeof(a[0]); i ++)
  18.     {
  19.         sum += a[i];
  20.         if(sum < 0)
  21.         {
  22.              if(sum > max)      /* 此时的sum即为 a[i],负值的情况只是简单的替换 */
  23.             {
  24.                 max = sum;
  25.                 start = i;
  26.             }
  27.             temp_start = i + 1;  /* 从下一个数组元素开始重新计算 */
  28.             sum = 0;      /* 舍弃前面的元素 */
  29.         }

  30.         else if(sum > max)   /* 此时sum不小于0,前面的元素都已舍弃 */
  31.         {
  32.             start = temp_start;  /* 找到新的和最大子数组,进行替换 */
  33.             max = sum;                  /* 替换最大值 */
  34.             len = i - start + 1;        /* 计算子数组长度 */
  35.         }
  36.     }

  37.     printf("start = %d, len = %d, max = %d\n", start, len, max);
  38.     return 0;
  39. }
复制代码

论坛徽章:
0
45 [报告]
发表于 2010-09-16 11:38 |只看该作者
回复 43# goubao198562


    你的这个begin的计算有问题,比如a[]={0, -3, -2, -4, -1}..  sbegin在sum<0分支会一直后加,这样得到begin就是错的了

论坛徽章:
0
46 [报告]
发表于 2010-09-16 13:29 |只看该作者
本帖最后由 chouy 于 2010-09-16 13:30 编辑

我在别的公司面试也遇到了这道题,当时没答出来,不过后来在家做出来了.
写在了我的BLOG中,地址如下:http://www.cublog.cn/u/10921/showart_2320089.html

论坛徽章:
0
47 [报告]
发表于 2010-09-16 13:52 |只看该作者
DP  啊
王晓东的算法书里面的例子

时间复杂度 O(N)

论坛徽章:
0
48 [报告]
发表于 2010-09-16 14:16 |只看该作者
回复 46# chouy

如果数组可以回绕的话,只需要对数组遍历两遍就可以了。
粗略的改了一下,可能有些错误。

  1. #include <stdio.h>

  2. int main()
  3. {
  4.     //int a[] = { -4, -3, -4, -7, -9, -6, -8, -1, -7};
  5.     //int a[] = {0, -1, -2, -3, 0, -4, -8};
  6.     //int a[] = {1, 1, -3, -3, -4, 3, 4, -8, 2, 3};
  7.     //int a[] = {1, -2, 5, -7, -2, 3};
  8.     //int a[] = {9, -12, 120, 8, -20, 100, 30, -89, 20};
  9.     int a[] = {9, -12, 120, 8, -20, 100, 30, -19, 20};
  10.     int start;          /* 子数组开始下标 */
  11.     int temp_start;     /* */
  12.     int len;            /* 子数组长度 */
  13.     int sum;            /* 临时计数 */
  14.     int max;            /* 子数组的和 */

  15.     int i = 0;
  16.     int array_size = sizeof(a)/sizeof(a[0]);
  17.     start = sum = temp_start = 0;
  18.     len = 1;
  19.     max = a[0];

  20.   //  for(i = 0; i < sizeof(a)/sizeof(a[0]); i ++)
  21.     while(i < 2*array_size - 1)
  22.     {
  23.         sum += a[i % array_size];

  24.         if(sum < 0)
  25.         {
  26.             if(sum > max)
  27.             {
  28.                 max = sum;
  29.                 start = i % array_size;
  30.             }
  31.             temp_start = i % array_size + 1;
  32.             sum = 0;
  33.         }
  34.         else if(sum > max && i - temp_start < array_size)
  35.         {
  36.             start = temp_start;         /* 发现比之前记录的子数组最大值要大的连续元素,替换开始位置 */
  37.             max = sum;                  /* 替换最大值 */
  38.             len = i - start + 1;        /* 计算子数组长度 */
  39.         }
  40.         i ++;
  41.     }

  42.     printf("start = %d, len = %d, max = %d\n", start, len, max);
  43.     return 0;
  44. }
复制代码

论坛徽章:
0
49 [报告]
发表于 2010-09-16 14:30 |只看该作者
回复 45# petery87


    对 是有问题

论坛徽章:
0
50 [报告]
发表于 2010-09-16 16:17 |只看该作者
从第一个依次往后加,  设置两个变量  max 记录曾达到的最大值 , max start 记录达到最大时的开始下标, m ...
goldenfort 发表于 2010-09-14 14:25



    说得很清楚了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP