繁体   English   中英

按字典顺序排列的 1…n 的 k 的组合,算法太慢

[英]Combinations of k of 1…n in lexycographical order, algorithm too slow

下面是一种方法(使用回溯),按字典顺序列出区间 [1,n] 之外的 k 个数字的所有可能组合。不允许重复。
IE:

输入:

5 3

output:

1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5

我想越来越多地构建序列:一旦我将第一个数组元素设置为 1,我只需要从 2 迭代到 e_m - (n - 2) 来获取第二个元素; 一旦后者达到 3,那么第三个元素只会从 4 变为 e_m - (n - 3) 等。我不知道该怎么做,请你帮忙吗? 下面的方法构建了所有 n 个数字 ≤ el_maxim 的序列,然后只显示那些增加的.. 在线编译器不会接受这个,因为它太慢了

#include <iostream>
using namespace std;
int sol[20], n , el_maxim;
void display()
{
    for (int i = 0; i < n; i++)
        cout << sol[i] << " ";
    cout << endl;
}
int okay()
{
    for (int i = 0; i < n - 1; i++)
        if (sol[i] >= sol[i + 1])
            return 0;
    return 1;
}
void bkt(int poz)
{
    if (poz == n)
    {
        okay();
        if (okay() == 1)
            display();
    }
    else
        for (int i = 1; i <= el_maxim; i++)
        {
            sol[poz] = i;
            bkt(poz + 1);
        }
}
int main()
{
    cin >> el_maxim >> n;
    bkt(0);
    return 0;
}

这是一些工作代码。 这个想法是记住您使用的最后一个元素,以免再次尝试使用它。 您可以使用参数记住 function 调用之间的变量。

为了加快速度,您可以删除okay() function 并在到达pos == n时始终调用display() ,因为可以保证当您到达它时您有一个正确的答案。 我在我的代码中做到了这一点。

#include <iostream>

using namespace std;
int sol[20], n , el_maxim;
void display()
{
    for (int i = 0; i < n; i++)
        cout << sol[i] << " ";
    cout << endl;
}
void bkt(int poz, int last_element)
{
    if (poz == n)
    {
         display();
    }
    else{
        for (int i = last_element + 1; i <= el_maxim; i++)
        {
            sol[poz] = i;
            bkt(poz + 1, i);
        }
    }
}
int main()
{
    cin >> el_maxim >> n;
    bkt(0, 0);
    return 0;
}

一个简单的详尽搜索就足够了。 如果将来不需要 arrays,我们也可以在O(K)额外空间中进行操作。

#include <iostream>
#include <vector>

using namespace std;

void foo(vector<int>& sol, int N, int K, int n = 1, int k = 1)
{
    if (k > K)
    {
        for (int e : sol)
            cout << e << ' ';
        cout << endl;
        return;
    }

    for (int i = n; i <= N; ++i)
    {
        sol.push_back(i);
        foo(sol, N, K, i + 1, k + 1);
        sol.pop_back();
    }
}

int main()
{
    int N, K;
    cin >> N >> K;

    vector<int> sol;
    foo(sol, N, K);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM