zoukankan      html  css  js  c++  java
  • 经典面试题 之 子数组之和最大值

    因为最近要开始笔试和面试了,我觉得,很有必要做好准备~

    这个问题是我在网上看到的,13年一家公司的笔试题,求子数组的最大和。这个题我之前在微软的编程之美看到过,不过当时记得并不是很深刻。

    现在既然看到了,我就好好的想了想。考试题如下:

    上面只给了两行代码的空间,也就是说,只需要两行的代码即可。

    对于这个问题,有种很简单,但是效率最低的方法,就是枚举出全部的子数组,并且求和,比较出最大值。我当初写的代码就是这个版本的,现在应该在实验室的电脑里。

    但是,在《编程之美》中,对于这个问题提供了三种解法,而且其中的第三种是效率最高的。时间复杂度O(n),空间复杂度为O(1)。

    其实可以考虑一种比较极端的情况,就是,只有两个数,A[0] and A[1]。

    这样,最大值存在的情况,无非就是:A[0], A[0] + A[1], A[1]。

    这个过程基本就是三个数字中,找到最大值的过程。

    然后推广到n的时候,从0->n - 1遍历只要重复这个过程,就能简单的获取到最终的最大值。

    那么如何推广?

    假设现在有三个数字A[3]:A[0] A[1] A[2].

    这样先比较前两个元素,A[0],A[1],以及A[0] + A[1]。因为下次的比较需要将前面的A[0]+A[1]作为一个整体加入到下一次的比较中,所以需要有一个值能够用来表示其和。这个变量就是上面的nStart。

    nAll则是相当于每次比较中的A[0]。那么每次的比较的顺序就是:A[1]和A[0] + A[1]比较。nStart取其最大值,然后在和相当于A[0]的nAll比较。如此往复,当线性遍历结束的时候,就成功的获取到了最大值。

    这个方法相当巧妙,其中很多的细节都要自己慢慢的体会。

    程序演示截图:

    程序代码:

     1 #include <iostream>
     2 
     3 using namespace std;
     4 #define max(a, b) (a) > (b) ? (a) : (b)
     5 int MaxSubArray(int * A, int n)
     6 {
     7     int nStart = A[0];
     8     int nAll = A[0];
     9     for(int i = 1;i < n;++ i)
    10     {
    11         nStart = max(A[i], nStart + A[i]);
    12         nAll = max(nStart, nAll);
    13     }
    14     return nAll;
    15 }
    16 int main()
    17 {
    18     cout << "Hello world!" << endl;
    19     int array[] = {10, -1, 3, -11, -20, 33, 1, -6, 13};
    20     cout << MaxSubArray(array, sizeof(array)/sizeof(int)) << endl;
    21     return 0;
    22 }
  • 相关阅读:
    Centos 6.4 8250/16550 只生成了4个串口
    Warning: Data truncated for column 'AirPress' at row 1
    I.MX6 32G SD卡测试
    oracle创建数据库表空间
    oracle创建表空间
    SpringMvc文件下载
    怎么取消ie浏览器body与html的间隙
    Ztree手风琴效果(第三版)
    判断JS对象是否拥有某属性
    js代码判断浏览器种类IE、FF、Opera、Safari、chrome及版本
  • 原文地址:https://www.cnblogs.com/matrix-r/p/3319053.html
Copyright © 2011-2022 走看看