问题描述

https://leetcode.com/problems/permutation-sequence/#/description

he 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):

  1. "123"
  2. "132"
  3. "213"
  4. "231"
  5. "312"
  6. "321"

Given n and k, return the kth permutation sequence.

Note: Given n will be between 1 and 9 inclusive.

求n个数字组成的所有全排列字符串中的第k个字符串。

算法

因为只要求1个,所以可以按照全排列的规则,一个个数的求出每个位置的数字,而不需要将所有的全排列字符串列出来。

对于n个字符组成的字符串{1,2,3,...,n},取第k个数时,首先可以求出第一个数,即(k-1)/(n-1个数的排列个数)

比如n=3,k=4时,全排列组合为:

  1. 1 + {2,3}的全排列
  2. 2 + {1,3}的全排列
  3. 3 + {1,2}的全排列

我们可以首先求出目标排序的第一个数字,即(k-1)/(两个数的排列数) = (k-1)/2 = 3/2 = 1,下标从0开始,下标1表示的数就是2

接下来,就是求出{1,3}全排列中排在第 k-2=2 个位置上的数,方法同3个字母时一样,求出结果后为 231

所以,可以一层一层的求出第k个顺序的字符串。

时间复杂度为O(N)

一开始是以递归形式写的算法,相对容易理解,但速度慢,所以又写了循环版本的。

代码

循环版本

public String getPermutation(int n, int k) {
			char[] nums = new char[]{'1','2','3','4','5','6','7','8','9'};
	        String tmp = "";
	        for(int i=0;i<n;i++) {
	        	tmp += nums[i];
	        }
	        StringBuffer s = new StringBuffer(tmp);
	        String r = "";
	        while(k>0&&!s.toString().equals("")) {
	        	// 计算 (n-1)的排列个数cnt
	        	int cnt = 1, i = s.length()-1;
		    	while(i > 1) {
		    		cnt*=i;
		    		i-=1;
		    	}
		    	int pos = (k-1)/cnt;
		    	r += s.charAt(pos);
		    	s = s.deleteCharAt(pos);
		    	k -= pos * cnt;
	        }
	        return r;
		}

递归版本

 public String getPermutation1(int n, int k) {
	    	char[] nums = new char[]{'1','2','3','4','5','6','7','8','9'};
	        String s = "";
	        for(int i=0;i<n;i++) {
	        	s += nums[i];
	        }
	        return fun(new StringBuffer(s), k);
	    }
	    
	    public String fun(StringBuffer s, int k) {
	    	if(k<0 || s.toString().equals("")) return "";
	    	int cnt = 1, tmp = s.length()-1;
	    	while(tmp > 1) {
	    		cnt*=tmp;
	    		tmp-=1;
	    	}
	    	int pos = (k-1)/cnt;
	    	return s.charAt(pos) + fun(s.deleteCharAt(pos), k - pos*cnt);
	    }

LeetCode解题代码仓库:https://github.com/zgljl2012/leetcode-java


我的微信公众号
![](http://upload-images.jianshu.io/upload_images/3093748-7c07998b7495defc.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)