C ++算法优化:从N个元素中找到K组合

时间:2014-11-17 06:42:34

标签: c++ algorithm optimization

我对C ++非常不满意,并且正在努力做一些HackerRank挑战作为一种方法来解决这个问题。
现在我正试图解决愤怒的孩子问题:https://www.hackerrank.com/challenges/angry-children

基本上,它要求创建一个给出一组N整数的程序,找到尽可能小的"不公平"对于该集合的K长度子集。不公平定义为K长度子集的最大值和最小值之间的差异。

我现在的方法是找到所有K长子集并计算它们的不公平性,跟踪最小的不公平性。

我编写了以下似乎正确问题的C ++程序:

#include <cmath>
#include <cstdio>
#include <iostream>

using namespace std;

int unfairness = -1;
int N, K, minc, maxc, ufair;
int *candies, *subset;

void check() {
    ufair = 0;
    minc = subset[0];
    maxc = subset[0];

    for (int i = 0; i < K; i++) {
        minc = min(minc,subset[i]);
        maxc = max(maxc, subset[i]);
    }

    ufair = maxc - minc;

    if (ufair < unfairness || unfairness == -1) {
        unfairness = ufair;
    }
}

void process(int subsetSize, int nextIndex) {
    if (subsetSize == K) {
        check();
    } else {
        for (int j = nextIndex; j < N; j++) {
            subset[subsetSize] = candies[j];
            process(subsetSize + 1, j + 1);
        }
    }
}

int main() {
    cin >> N >> K;
    candies = new int[N];
    subset = new int[K];

    for (int i = 0; i < N; i++)
        cin >> candies[i];

    process(0, 0);

    cout << unfairness << endl;

    return 0;
}

问题是HackerRank要求程序在3秒内提出解决方案,并且我的程序需要更长时间才能找到12/16测试用例的解决方案。例如,其中一个测试用例的N = 50,K = 8;该程序需要8秒钟才能在我的机器上找到解决方案。我该怎么做才能优化我的算法?我对C ++不是很熟悉。

2 个答案:

答案 0 :(得分:1)

我给出的一个建议是在选择子集之前对整数列表进行排序。这将大大减少您需要检查的子集数量。事实上,您甚至不需要创建子集,只需查看索引i(从0开始)和i + k的元素,以及i和i + k [在有效范围内]的所有元素的最低差异]是你的答案。所以现在而不是选择k子集(我认为是因子运行时)你只需要查看~n子集(线性运行时)和排序(nlogn)就会成为你性能的瓶颈。

答案 1 :(得分:1)

您所要做的就是按升序对所有数字进行排序,然后从a[i + K - 1] - a[i]i包含所有0的最小N - K。 这是事实,因为在最佳子集中,所有数字都连续位于有序数组中。