数组中两个元素的最大乘积,由8个或更多个位置分隔

时间:2016-03-19 16:11:32

标签: c++ c algorithm time-complexity

这是我到目前为止所遇到的问题和代码。

我有一系列正数。序列的长度大于8,负数(不是序列的一部分)是序列末端的符号。我需要编写一个程序(通过时间和内存使用有效),找到由8个或更多位置分隔的2个元素的最大乘积。保证答案小于2000000000。

例如,对于{1 2 3 4 5 6 7 8 9 10 -1},答案为20

我的代码:

#include <stdio.h>
#include <stdlib.h>

static long long int find_max(long int *v1, long int size) {
    const int d = 8;
    long int arr[8];
    long int maxi = 0;  
    long long int max_pr = 0;

    for (int i = 1; i < d + 1; i++) {
        arr[i % d] = v1[i - 1];
    }
    for (int j = d + 1; j < size + 1; j++) {
        if (arr[j % d] > maxi)
            maxi = arr[j % d];
        if (v1[j - 1] * maxi > max_pr)
            max_pr = v1[j - 1] * maxi;
        arr[j % d] = v1[j - 1];
    }
    return max_pr;
}

int main() {
    long int seq[100000];
    long int n = 0;

    while (n < 100000 && scanf("%ld", &seq[n]) == 1) {
        if (seq[n] < 0) {
            break;    //vector.push_back was too slow
        }
        n++;
    }

    long long int answer = find_max(seq, n);
    printf("%lld ", answer);

    return 0;
}

这是关于算法和数据结构的开放课程的作业问题,与我的学位无关。我的代码在测试系统上失败了。我已经尝试解决这个问题几天了,并且无法理解我在这里做错了什么,因为它对我能提出的每个例子都很好。

我真的很感激任何帮助。

2 个答案:

答案 0 :(得分:3)

这很容易在线性时间内完成,无需任何额外的存储空间。想想哪些数字可能是可能的解决方案:它可能是第九个数字的第一个数字。它可能是前两个中最大的,也就是第十个中的最大值。它可能是前三个中最大的,第十一个,依此类推。所以:

Set maxN = 0, maxProduct = 0, i = 0. 
As long as v1 [i + 8] ≥ 0:
    If v1 [i] > maxN then maxN = v1 [i]
    If v1 [i + 8] * maxN > maxProduct then maxProduct = v1 [i + 8] * maxN.
    Let i = i + 1.

就是这样。

答案 1 :(得分:1)

您的算法没有按照问题要求您执行此操作。特别是,arr[8]i%d不是必需的。

以下是如何在O(n)时间内解决此问题的方法,该方法效率最高:

  • 创建一个大小等于数组大小的数组maxSoFar
  • 从左到右走数组seq。将maxSoFar[i]设置为seq
  • 左侧i的最高值
  • 从索引seq开始再次遍历数组8,找到max的{​​{1}}。

以下是随机序列seq[i] * maxSoFar[i-8]的示例:

maxSoFar

第二遍应该产生以下值:

seq:             1 4 3 5 2 12  8  6 14 19  7  9 25 20 13
maxSoFar:        1 4 4 5 5 12 12 12 14 19 19 19 25 25 25

因此,结果是240。

注意:可以删除数组maxSoFar。你能看到怎么样?