全排列 字典序全排列

全排列递归的方法参考 leetcode 47

字典序算法:升序

参考https://www.jianshu.com/p/58ae30cf6bca

实现:

判断了是否相等

计算全排列的数量方法为 n!/ (m!*p!*...)   m,p为重复的数字的重复量

参考 https://blog.csdn.net/sinat_36215255/article/details/78197129

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

void Permutation(int len,vector<int>nums)
    {
        int j, k;
        int flag=1;  //start 0s
        while (true)
        {
        for(int i=0;i<len;i++){
                if(nums[i]==0&&flag)
                        continue;
                else{
                        flag=0;
                        printf("%d",nums[i]);
                }
        }
        printf(" ");
        flag=1;

        for (j = len - 2; j >= 0 && nums[j] >= nums[j + 1]; j--);//注意此处 j >= 0 判断条件在前,加个等号即可  

        if (j < 0) return;//结束  

        for (k = len - 1; k > j&&nums[k] <= nums[j]; k--);//加个等号即可  

        swap(nums[k], nums[j]);  

        for (int l = j + 1, r = len - 1; l < r; l++, r--)
                swap(nums[l], nums[r]);
        }
    }

int calc(int len){
        int summ=1;

        for(int i=1;i<=len;i++)
                summ*=i;
        return summ;
}
int main()
    {  

        int n;
        while(cin>>n)
        nums.push_back(n);
        sort(nums.begin(),nums.end());
        int len=nums.size();

        //all 0
        int flag=0;
        for(int i=0;i<len;i++)
                if(nums[i]!=0){
                        flag==1;
                        break;
                }
        if(flag)
        {
                cout<<"1 0"<<endl;
                return 0;
        }

        vector<int>dup;
        int cnt=1;
        int bef=nums[0];
        for(int i=1;i<len;i++)
                if(bef==nums[i]){
                        cnt++;
                        continue;
                }
                else
                {
                        dup.push_back(cnt);
                        cnt=1;
                        bef=nums[i];
                }

        //dup.push_back(cnt);
        vector<int>::iterator iter=dup.begin();
        int divide=1;
        for(iter;iter!=dup.end();iter++)
                divide*=calc(*iter);
        int summ=calc(len)/divide;
        printf("%d ",summ);

        Permutation(len,nums);
        system("pause");
        return 0;
    }

原文地址:https://www.cnblogs.com/lqerio/p/12079873.html

时间: 2024-11-03 22:47:22

全排列 字典序全排列的相关文章

字典序全排列(java实现)

import java.util.Arrays; /** *字典序全排列 *字符串的全排列 *比如单词"too" 它的全排列是"oot","oto","too" *1,从右端开始扫描,若出现前一个比好一个小,记录前一个的元素下表index *2,再找出index以后比该元素大的中的最小值的下标,(实现见 下面的getMin方法) *3,index以后的元素实现反转(实现 见下面的reverse方法) *结束条件:前一个都比后一

java字典序全排列

import java.util.Arrays; /** *字典序全排列 *字符串的全排列 *比如单词"too" 它的全排列是"oot","oto","too" *1,从右端开始扫描,若出现前一个比后一个小,记录前一个的元素下表index *2,再找出index以后比该元素大的中的最小值的下标,(实现见 下面的getMin方法) *3,index以后的元素实现反转(实现 见下面的reverse方法) *结束条件:前一个都比后一

HDOJ-ACM1016(JAVA) 字典序全排列,并剪枝

转载声明:原文转自http://www.cnblogs.com/xiezie/p/5576273.html 题意: 一个环是用图中所示的n个圆组成的.把自然数1.2.…….n分别放入每个圆中,并在相邻的圆中的数值总和为一个质数. 注:第一圈数应该是1. 输出: 输出格式显示为下面的示例.每一行代表在环里圆中的数从1开始顺时针和逆时针.数字的数量必须满足上述要求.按字典顺序打印解决方案. 你是写一个程序,完成上述过程. 每一种情况下打印一条空白线. 题目分析: 首先,因为需要遍历多次,质数不可能每

【codeup】1959: 全排列 及全排列算法详解

题目描述 给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列.我们假设对于小写字母有'a' < 'b' < ... < 'y' < 'z',而且给定的字符串中的字母已经按照从小到大的顺序排列. 输入 输入只有一行,是一个由不同的小写字母组成的字符串,已知字符串的长度在1到6之间. 输出 输出这个字符串的所有排列方式,每行一个排列.要求字母序比较小的排列在前面.字母序如下定义:已知S = s1s2...sk , T = t1t2...tk,则S < T 等价于,存

分治法实现1-N的数字按字典序全排列组合 Java语言

package 分治法; import java.util.Arrays; /* * 将数字 1 - n进行全排列 按字典序从小到大输出 * 如 1 - 3 * 123 132 213 231 312 321 */ class GenerateP{ private int n; // 求 1-n所有数字的全排列 private final int maxn = 110;//最多可排列组合的长度 1-100 private boolean [] hashTable; private int []

字典序全排列

给出正整数n,则1~n这n个数可以构成n!种排列,把这些排列按照从小到大的顺序(字典顺序)列出,如n=3时,列出1 2 3,1 3 2,2 1 3,2 3 1,3 1 2,3 2 1 这6个排列. 字典序算法如下: 假设这n个数的某一个排列为 P: P1 P2 P3...Pj-1 Pj Pj+1...Pk-1 Pk Pk+1...Pn 1.从该序列的最右端开始向左找出第一个比与自己相邻的右边数小的数,记其下标为j,即j = max{i|Pi<pi+1}. 2.找出Pj右边比Pj大的最小数Pk.

POJ 3785 The Next Permutation 全排列字典序法

给一个排列  求下一个排列 按字典序 跟普通排列不同的地方就是 有相同的数字 那么就把普通的一改就完事 #include <iostream> #include <cstdio> #include <cstring> #include <vector> #include <queue> #include <cmath> #include <algorithm> #include <map> #include &

全排列的几种实现(含字典序排列算法分析)

始于一个很简单的问题:生成{0,1,2,3,...,n-1}的n!种排列,即全排列问题.下面介绍几种全排列的实现,以及探讨一下其解题思路. 基于枚举/递归的方法 思路: 基于枚举的方法,也可以说是基于递归的方法,此方法的思路是先将全排列问题的约束进行放松,形成一个较容易解决的新问题,解新问题,再对新问题进行约束,解出当前问题.以上全排列问题是生成{0,1,2,...,n-1}的n!个排列,隐含的一个约束是这个n个位置上的数必须是给出的集合中的数,不能重复使用.当我们将此约束放松的时候,问题就变成

[全排列]基于逆序列的字典序法的改进

摘要: 字典序法是生成全排列的经典算法.本文在对字典序法进行分析的基础上,提出了一种基于逆序列的改进字典序全排列生成算法.通过与传统的四种全排列生成算法进行对比,本文方法可以大大提高全排列的生成效率.关键词:全排列;字典序;逆序列 基于逆序列的字典序法的改进 code