当前位置: 首页 > 知识库问答 >
问题:

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

欧阳俊逸
2023-03-14

我对C很在行,我正在尝试做一些黑客挑战,以此作为解决这个问题的方法
现在我正在努力解决愤怒的孩子们的问题: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个答案

池庆
2023-03-14

我的一个建议是在选择子集之前对整数列表进行排序。这将大大减少需要检查的子集的数量。事实上,您甚至不需要创建子集,只需查看索引i(从0开始)和ik处的元素,i和ik处所有元素的最低差值[有效边界]就是您的答案。因此,现在您不必选择n个子集(我相信是阶乘运行时),而只需查看~n个子集(线性运行时),排序(nlogn)就会成为性能瓶颈。

仉成益
2023-03-14

你所要做的就是对所有的数字进行升序排序,然后得到最小的a[i K-1]-a[i]所有i0N-K>包括在内。这是真的,因为在最优子集中,所有数字都依次位于排序数组中。

 类似资料:
  • 问题内容: 我想编写一个函数,该函数以字母数组作为参数,并选择多个字母。 假设您提供8个字母的数组,并希望从中选择3个字母。然后您将获得: 返回由3个字母组成的数组(或单词)。 问题答案: 格雷码您会遇到的一个问题当然是记忆力,而且很快,您的集合中会有20个元素出现问题-20 C 3 =1140。而且,如果要遍历集合,最好使用修改后的灰色代码算法,因此您不必将所有代码都保存在内存中。这些将根据之前

  • 我有一个运行的整数流,如何在任何时间点从这个流中获取最大的k个元素。

  • 问题描述 这道题是 LeetCode 77 题。 给定两个整数 n 和 k,返回 1 … n 中所有可能的 k 个数的组合。 解法一:回溯法 递归 k 层。每层选取一个数,然后递归地选取 k-1 个数,直到选够 k 个数为止。设每层的数字区间为 [start, end],则这一层可以选择 [start, end-(k-1)] 的任何一个数 i,只要给下一层留出 k-1 个数即可。下一层的数字区间为

  • 这是一个算法问题。如果我错过了Python中任何有帮助的现有函数,请大喊一声。 给定一组元素的,我们可以在Python中使用函数来找到所有唯一的k元素子集。让我们调用包含所有这些子集的集合。请注意,每个这样的子集都有不同的元素。 问题是两步走。首先,给定这些k-不同元素子集,我想组合(其中的一些),这样(组合只是一些子集的超集): > 构图中任意两个子集之间的交集为空 构图中所有子集的并集给出的正

  • 本文向大家介绍从Python中的元组列表中找到前K个频繁元素,包括了从Python中的元组列表中找到前K个频繁元素的使用技巧和注意事项,需要的朋友参考一下 我们有一个元组列表。在其中,我们需要找到前k个频繁元素。如果k为3,则需要从列表中的元组中找到前三个元素。 使用defaultdict 我们使用defaultdict将元素放入字典容器中。然后仅找出满足前k个条件的元素。 示例 输出结果 运行上

  • 我试图写一个算法,它需要可变数量的通用数组,存储在中,并收集其中所有唯一的元素(元素只发生一次),并将其存储在一个数组中,称为。例如,数组: 将生成包含内容的数组。 以下是我当前的流程算法: 请注意,是一个数组,它包含