我对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 ++不是很熟悉。
答案 0 :(得分:1)
我给出的一个建议是在选择子集之前对整数列表进行排序。这将大大减少您需要检查的子集数量。事实上,您甚至不需要创建子集,只需查看索引i(从0开始)和i + k的元素,以及i和i + k [在有效范围内]的所有元素的最低差异]是你的答案。所以现在而不是选择k子集(我认为是因子运行时)你只需要查看~n子集(线性运行时)和排序(nlogn)就会成为你性能的瓶颈。
答案 1 :(得分:1)
您所要做的就是按升序对所有数字进行排序,然后从a[i + K - 1] - a[i]
到i
包含所有0
的最小N - K
。
这是事实,因为在最佳子集中,所有数字都连续位于有序数组中。