求序列的全排列(C++ )

作者: 零岁的我 | 来源:发表于2020-05-21 12:09 被阅读0次

求全排列并不难,但是在一些问题求解过程中经常需要用到,例如典型的24点游戏问题。下面直接上代码了,参考注释不难看懂。

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

void display(array<int,4> arr)
{
    for(auto value:arr){
        cout<<value<<" ";
    }
    cout<<endl;
}

/*
对于包含相同元素的序列来说,只要一个序列中的元素顺序不同,就是一种排列。
next_permutation() 会生成一个序列的重排列,它是所有可能的字典序中的下
一个排列,默认使用 < 运算符来做这些事情。它的参数为定义序列的迭代器和一个
返回布尔值的函数,这个函数在下一个排列大于上一个排列时返回 true,如果上一
个排列是序列中最大的,它返回 false,所以会生成字典序最小的排列。
所以想通过next_permutation()来获得一个序列的全排列,就要保证初始状态下,
序列是字典序中最小的,这样通过next_permutation()循环才能生成完整的排列
*/
void getPermutation1(array<int,4> arr)
{
    sort(arr.begin(),arr.end());  //如果将此行注释,最终结果会不完整
    do{
        display(arr);
    }while(next_permutation(arr.begin(),arr.end()));
}

//回溯法求排列组合
int getPermutation2(array<int,4> arr,int index)
{
    //触发结束条件
    if(index==4){
        display(arr);
        return 0;
    }
    for(int i=index;i<4;++i){
        //做选择
        int temp=arr[index];
        arr[index] = arr[i];
        arr[i] = temp;
        getPermutation2(arr,index+1); //进入下一层决策树
        //取消选择
        temp=arr[index];
        arr[index] = arr[i];
        arr[i] = temp;
    }
    return 0;
}

int main(int argc,char **argv)
{
    array<int,4> arr={3,2,1,0};
    cout<<"----基于字典序的排列组合----"<<endl;
    getPermutation1(arr);
    cout<<"----回溯算法求得的排列组合----"<<endl;
    getPermutation2(arr,0);
    return 0;
}

运行结果截图如下:

基于字典序的排列组合 回溯算法求排列组合

next_permutation()算法原理可以参考我上一篇字典序算法笔记

以上只是简单的打印求得的排列,如果想要保存全排列结果,可以借助二维数组。下面还是基于回溯算法的求解全排列过程,只不过将求得的全排列放在二维数组里了。

/*题目描述: 
给定一个不包含重复的数组,返回所有可能的排列。
*/
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

//回溯算法   
void backtrack(vector<int>& nums, vector<vector<int>>& result, vector<int>& path){
    //触发结束条件
    if(path.size() == nums.size()){
        vector<int> temp = path;
        result.push_back(temp);
    }else{
        for(int i = 0; i< nums.size(); i++) {
            //排除不合法的选择
            if(find(path.begin(), path.end(),nums[i]) != path.end()) continue;
            path.push_back(nums[i]); //做选择
            backtrack(nums, result, path); //进入下一层决策树
            path.pop_back(); //取消选择
        }
    }
}

vector<vector<int> > permute(vector<int>& nums) {
    vector<vector<int> > result;
    vector<int> path; //记录临时路劲
    backtrack(nums, result, path);
    return result;
}

void display(vector<vector<int> > v)
{
    for(auto arr:v){
        for(auto value:arr){
            cout<<value<<" ";
        }
        cout<<endl;
    }
    cout<<endl;
}

int main(int argc,char **argv)
{
    int a[]={3,2,1,0};
    vector<int> v(a,a+4);
    vector<vector<int> > result;
    result=permute(v);
    display(result);
    return 0;
}

相关文章

  • 求序列的全排列(C++ )

    求全排列并不难,但是在一些问题求解过程中经常需要用到,例如典型的24点游戏问题。下面直接上代码了,参考注释不难看懂...

  • 递增全排列算法

    问题 给定一个递增序列其中,,若,则。求它的递增全排列集合。 所谓递增全排列是这样一个有序集合:其中是序列的一个全...

  • 全排列

    问题描述 求1-n的所有按字典序的全排列 C++实现

  • JavaScript#31:数组--(字典排序)Next Per

    求一个序列的下一个全排列...........按照字典序。 所谓字典序,比如说 123三个数字组成的全排列就有: ...

  • Leetcode 46. 全排列

    题目 给定一个没有重复数字的序列,返回其所有可能的全排列。 示例: C++解法 来源:力扣(LeetCode)链接...

  • 【leetcode】全排列

    【leetcode】全排列 题目: 给定一个 没有重复 数字的序列,返回其所有可能的全排列。 示例: 输入: [1...

  • 递归与回溯:python列表排列问题

    给定一个 没有重复 数字的序列,返回其所有可能的全排列。 给定一个有重复 数字的序列,返回其所有可能的全排列且不重复

  • 关于数组的一些操作【python】

    递归的应用:求输入字符串的全排列 求输入字符串的全排列递归完成,也可以直接使用库函数 结果展示: ————————...

  • LeetCode-46-全排列

    LeetCode-46-全排列 题目 给定一个没有重复数字的序列,返回其所有可能的全排列。 示例: 输入: [1,...

  • 每周 ARTS 第 19 期

    1. Algorithm 46. 全排列(中等) 描述: 给定一个没有重复数字的序列,返回其所有可能的全排列。 示...

网友评论

    本文标题:求序列的全排列(C++ )

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