Permutation

来源:互联网 发布:淘宝怎么看确认收货 编辑:程序博客网 时间:2024/04/30 15:54
  • Permutation全排列

给定当前排列,如何得到下一个排列

1. 对于排列a[1...n],找到所有满足a[k] < a[k+1] 的k的最大值,如果这样的k不存在,则说明当前排列已经是a的所有排列中字典序最大者,所有排列输出完毕。2.a[k+1...n]中,寻找满足这样条件的元素l,使得在所有a[l]>a[k]的元素中,a[l]取得最小值。也就是说a[l]>a[k],但是小于所有其他大于a[k]的元素。3. 交换a[l]与a[k].4. 对于a[k+1...n],反转该区间内元素的顺序。这样就得到了a[1...n]在字典序中的下一个排列。
public class Solution {    public void nextPermutation(int[] nums) {        if(nums==null || nums.length <= 1)            return;        int i=nums.length-2;        while(i>=0 && nums[i]>=nums[i+1]) i--;        if(i>=0){            int j = nums.length-1;            while(nums[j]<=nums[i])j--;            sw(nums,i,j);        }        re(nums,i+1,nums.length-1);    }    public void sw(int[] nums,int i,int j){        int tmp = nums[i];        nums[i]=nums[j];        nums[j]=tmp;    }    public void re(int[] nums,int i,int j){        while(i<j)            sw(nums,i++,j--);    }}
STL中有next_permutation这个函数

找到前一个排列的算法和找下一个的算法类似


给定n,选择n中的m个数进行全排列,并输出。例如n=3 m=1 输出为1 2 3
递归,搜索

#include<cstdio>#include<cstring>int visit[10];int a[10];int n,m;void permutation(int i){    int j,k;    if(i>m)    {        for(k=1;k<=m;++k)            printf("%d",a[k]);        printf("\n");    }    else    {        for(j=1;j<=n;++j)        {            if(visit[j]==0)            {                visit[j]=1;                a[i]=j;                permutation(i+1);                visit[j]=0;            }        }    }}int main(){    int T;    scanf("%d",&T);    while(T--)    {        scanf("%d%d",&n,&m);        memset(visit,0,sizeof(int));        permutation(1);    }    return 0;}

给定一个排序,输出在全排列中排第几 或者 给定n,输出全排列中第n个排列

康托展开公式

X=an*(n-1)!+an-1*(n-2)!+…+ai*(i-1)!+…+a2*1!+a1*0!
其中a[i]为当前未出现的元素中是排在第几个(从0开始)
适用范围:没有重复元素的全排列

题目:找出第16个n = 5的序列(12345)首先第十六个也就是要前面有15个数1. 根据第一行的那个全排列公式,15 / 4! = 0 …15  =》  有0个数比他小的数是1,所以第一位是12. 拿走刚才的余数15,用15 / 3! = 2 …3   =>  剩下的数里有两个数比他小的是4(1已经没了),所以第二位是43. 拿走余数3, 用 3 / 2! = 1 …1   =》  剩下的数里有一个数比他小的是3,所以第三位是34. 拿走余数1, 用 1/  1! = 1 …0    =>  剩下的数里有一个数比他小的是 5(只剩2和5了),所以第四位是5所以排列是 1,4,3,5,2第二类题 :已知是n = 5,求14352是它的第几个序列?(同一道题)用刚才的那道题的 反向思维 :1. 第一位是1,有0个数小于1,即0* 4!2. 第二位是4,有2个数小于4,即2* 3!3. 第三位是3,有1个数小于3,即1* 2!4. 第四位是5,有1个数小于5,即1* 1!5. 第五位是2,不过不用算,因为肯定是0所以14352是 n = 5的第 0 + 12 + 2 + 1 + 0 = 15    + 1(求的是第几个,所以要加一) = 16
0 0
原创粉丝点击