美文网首页工作生活
使用next_permutation解决排列组合问题

使用next_permutation解决排列组合问题

作者: 漫游之光 | 来源:发表于2019-07-10 15:00 被阅读0次

next_permutation算法

next_permutation是C++中的一个函数,具体的作用是,对于一个给定的序列,对其重新排列,生成下一个排列,如何序列为最大序列,则将其重排为最小序列。还有一个对应的函数prev_permutation,这个函数是求前一个排列,如果是已经是最小的排列,则将其重排为最大的排列。next_permutation算法的具体步骤为:

  1. 从后向前查找第一个相邻元素对(i,j),并且满足A[i] < A[j]。
  2. 在[j,end)中寻找一个最小的k使其满足A[i]<A[k]。
  3. 将i与k交换。
  4. 逆置[j,end)。

下面给出一个简单的实现。

#include <iostream>
#include <algorithm>
using namespace std;

bool nextPermutation(int *begin, int *end){
    int *i,*j,*k,*x;
    for(x = end - 1;x > begin;--x){
        if(*(x-1) < *x ){
            i = x -1;
            j = x;
            break;
        }
    }
    if(x == begin){
        reverse(begin,end);
        return false;
    }   
    for(x=j,k=j;x<end;++x){
        if(*x < *k && *x > *i){
            k = x;
        }
    }
    iter_swap(i,k);
    reverse(j,end);
    return true;
}

int main(int argc, char const *argv[])
{
    int arr[] = {1,2,3,4};
    do{
        for_each(arr,arr+4,[](int a)->void{
            cout<<a<<" ";
        });
        cout<<endl;
    }while (nextPermutation(arr,arr + 4));
    return 0;
}

使用next_permutation求全排列

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main(int argc, char const *argv[])
{
    vector<int> v = {1,2,3,4};
    sort(v.begin(),v.end());
    do{
        for_each(v.begin(),v.end(),[](int a)->void{
            cout<<a<<" ";
        });
        cout<<endl;
    }while (next_permutation(v.begin(),v.end()));
    return 0;
}

使用next_permutation解决组合问题

这里有一个技巧,就是next_permutation函数支持重复元素,如果要求从n个元素中选择m个,可以对n-m个0和m个1进行全排列,其中,1代表选中,0代表不选中。对应的代码如下。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main(int argc, char const *argv[])
{
    vector<int> v = {1,2,3,4,5};
    int m = 2,n = 5;
    vector<int> choose(n-m,0);
    for(int i=0;i<m;i++){
        choose.push_back(1);
    }
    do{
        for(int i=0;i<choose.size();i++){
            if(choose[i] == 1){
                cout<<v[i]<<" ";
            }
        }
        cout<<endl;
    }while (next_permutation(choose.begin(),choose.end()));
    return 0;
}

使用深度优先搜索解决全排列问题

在没有接触到next_permutation这个函数之前,遇到排列问题我都是使用DFS解决的。

给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列。输入的字符串是排好序的。如输入abc,输出为:abc、acb、bac、bca、cab、cba。这个题目在一开始的时候,我不知道该怎么做,后来看了一个深搜的题目,发现和这个题目,很类似,然后就想到了解法。下面先给出代码:

#include<iostream>
#include <cstring>
using namespace std;

int len;
char array[10];
int visited[10];
char result[10];

void Dfs(int n){
    //如果是终点,直接返回 
    if(n==len+1){
        result[n] = '\0';
        cout<<result<<endl;
        return;
    }
    //找可以踩的点 
    for(int i=0;i<len;i++){
        if(visited[i] == 0){
            visited[i] = 1;
            result[n-1] = array[i];
            Dfs(n+1);//计算后面的全排列 
            visited[i] = 0;//计算完了,算下一个,这里要释放 
        }
    }
}

int main(){
    cin>>array;
    len = strlen(array);
    memset(visited,0,sizeof(visited));
    Dfs(1);
    return 0;
}

相关文章

  • 使用next_permutation解决排列组合问题

    next_permutation算法 next_permutation是C++中的一个函数,具体的作用是,对于一个...

  • 剪邮票

    next_permutation 二维数组 康拓 这个博客讲了怎么算排列组合的第N个数 也就是康拓和康拓逆展开ht...

  • Python实现字符串排序(包含了排列组合问题)

    用递归的方式解决排列组合问题 def zuhe(ss,res,path): if ss == '': ...

  • HJ89 24点运算

     解法思想,全排列+递归。 Reference[1] next_permutation 的原理和使用[https:...

  • 实现next_permutation函数

    问题,实现 STL 中的 next_permutation() . 回答来自stackoverflow: 先让我们...

  • 面试题,使用递归解决排列组合问题

    1. 面试题目 公司6人,3人一组,分组如下: 两两结合,表演节目。 其中A和a不能同一组(两个人有杀父之仇!) ...

  • reduce实现排列组合

    之前需求需要排列组合,然后参考这个链接后,发现了用js的高阶函数reduce去解决不定长二维数组的排列组合问题; ...

  • 排列组合问题

    排列组合问题 今天同事问了我一个问题,给定随机几个数字(不重复),列出其所有排列组合可能.这个问题看似很简单,毕竟...

  • 排列组合问题

    题目 给出一个二维数组,得到所有想要结果的二维数组。比如: 希望得到的结果 再比如: 希望得到的结果: 我的算法:...

  • 排列组合问题

    为什么要写这篇文章 排列组合问题在数学中占有重要的地位,其与概率论也有密切的关系。而且排列组合问题大量出现在求职笔...

网友评论

    本文标题:使用next_permutation解决排列组合问题

    本文链接:https://www.haomeiwen.com/subject/megncctx.html