《leetCode》:Permutation Sequence
2015-11-22 17:39
495 查看
题目描述
The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and labeling all of the permutations in order, We get the following sequence (ie, for n = 3): "123" "132" "213" "231" "312" "321" Given n and k, return the kth permutation sequence. Note: Given n will be between 1 and 9 inclusive.
题目大意:找到第k个排列。
思路
与找出n个数的全排列的思路一样,但是这里只需要我们找出第k个排列,因此,设置一个标志位flag,当其为flag为false时,表示已经找到第k个。#include<stdio.h> #include<stdlib.h> #include<string.h> /* 思路:递归法,要注意的是:结果是排序后的第k个结果 */ void swap(char *a,char *b){ char temp=*a; *a=*b; *b=temp; } void bubbleSort(char *arr,int begin,int length){ int i,j; for(i=begin;i<length;i++){ for(j=i+1;j<length;j++){ if(arr[i]>arr[j]){ swap(&arr[i],&arr[j]); } } } } bool flag=true; char *result; void getPermutate(char *arr,int len,int* k,int start){ if(arr==NULL||len<0){ return ; } if(start==len-1){//得到一种结果 if((*k)==1){//得到最终的结果 flag=false; for(int k=0;k<len;k++){ result[k]=arr[k]; } result[len]='\0'; } (*k)--; } else{ for(int i=start;i<len;i++){ if(flag){ swap(&arr[start],&arr[i]); bubbleSort(arr,start+1,len); getPermutate(arr,len,k,start+1); if(flag){ bubbleSort(arr,start+1,len); } } } } } char* getPermutation(int n, int k) { if(n<1||k<1){ return NULL; } flag=true; //开辟一段空间来保存结果 result=(char *)malloc((n+1)*sizeof(char)); if(result==NULL){ exit(EXIT_FAILURE); } char *s=(char *)malloc((n)*sizeof(char)); if(s==NULL){ exit(EXIT_FAILURE); } for(int i=0;i<n;i++){ s[i]=(char)(i+'1'); // printf("%c ",s[i]); } getPermutate(s,n,&k,0) ; return result; } int main(void){ int n,k; while(scanf("%d%d",&n,&k)!=EOF&&n>0&&k>0){ char *result=getPermutation(n,k); puts(result); } return 0; }
AC结果如下:
小结
虽然AC了,但是效率不高。可以寻找更好的方法来做。改进
此方法来源于:思路如下:
http://blog.csdn.net/doc_sgl/article/details/12840715
方法二:数学解法 在n!个排列中,第一位的元素总是(n-1)!一组出现的,也就说如果p = k / (n-1)!,那么排列的最开始一个元素一定是nums[p]。 假设有n个元素,第K个permutation是 a1, a2, a3, ..... ..., an 那么a1是哪一个数字呢? 那么这里,我们把a1去掉,那么剩下的permutation为 a2, a3, .... .... an, 共计n-1个元素。 n-1个元素共有(n-1)!组排列,那么这里就可以知道 设变量K1 = K a1 = K1 / (n-1)! 同理,a2的值可以推导为 a2 = K2 / (n-2)! K2 = K1 % (n-1)! ....... a(n-1) = K(n-1) / 1! K(n-1) = K(n-2) /2! an = K(n-1)
实现代码如下:
char* getPermutation(int n, int k) { if(n<1||k<1){ return NULL; } //开辟一段空间来保存结果 char* result=(char *)malloc((n+1)*sizeof(char)); if(result==NULL){ exit(EXIT_FAILURE); } //开辟一段空间,来保存1~n的字符 char *s=(char *)malloc((n)*sizeof(char)); if(s==NULL){ exit(EXIT_FAILURE); } int count=1; //用来表示n! for(int i=0;i<n;i++){ s[i]=(char)(i+'1'); count*=(i+1); } //求结果中每一位对应的字符 k--;//减一的原因在于:第(n-1)!个排列应该是以1开头的最后一个排列;如果不减一,将会是以2开头的第一个 for(int i=0;i<n;i++){ count=count/(n-i); int index=k/count; result[i]=s[index]; for(int j=index;j<n-i-1;j++){//将s后面的元素提前 s[j]=s[j+1]; } //更新k k=k%count; } result ='\0'; return result; }
遇到的问题
1、当要求输出第k个排列时,原始代码实现的是:输出第k+1个排列,就报了如下错误。解决方法:在开始之前,将k减1.//减一的原因在于:第(n-1)!个排列应该是以1开头的最后一个排列;如果不减一,将会是以2开头的第一个
最后AC的结果如下:
相关文章推荐
- 1017. Queueing at Bank
- ios UITableView 入门
- Easyui简单布局
- UIButton
- Arduino 学习上拉电阻和下拉电阻遇到的问题
- UIBezierPath绘制图形
- java获取request的 ip port
- UIView
- LeetCode 063 Unique Paths II
- Android(13)java中的线程回顾,Android线程,主线程(UI线程)
- POJ1679The Unique MST(次小生成树)
- 第九章 UI布局管理器
- break continue详解
- 第八章 高级UI组件
- easyui环境搭建02
- Unique Paths II-leetcode
- cocoapods 0.35.0 版本 报错 Parsing unable to continue due to parsing error:
- UIBezierPath的自定义路径绘图
- LeetCode 062 Unique Paths
- CALayer 为什么选择 cg 开头 而 不选择 UI 开头