LeetCode060——第k个排列

版权声明:版权所有,转载请注明原网址链接。 https://blog.csdn.net/qq_41231926/article/details/82834088

我的LeetCode代码仓:https://github.com/617076674/LeetCode

原题链接:https://leetcode-cn.com/problems/permutation-sequence/description/

题目描述:

知识点:递归、回溯

思路一:求出所有的排列,取第k个排列(在LeetCode中提交会超时)

该思路之所以超时,是因为求解了许多不需要的信息。题目只要求第k个排列,可是根据该思路。我们可以求出第任意个排列。也就是说,我们在求出第k个排列的时候,额外多求了其余的排列。

时间复杂度是O(n !),空间复杂度是O(n)。

JAVA代码:

public class Solution {
	
	List<String> list;

	public String getPermutation(int n, int k) {
        list = new ArrayList<>();
        getPermutationUp("", 0, n, k);
        return list.get(k - 1);
    }
	
	//string consists of index numbers, we are going to consider the index + 1 number
	private void getPermutationUp(String string, int index, int n, int k) {
		if(index == n) {
			list.add(string);
			return;
		}
		for (int i = 1; i <= n; i++) {
			if(string.indexOf('0' + i) == -1) {
				string += i;
				getPermutationUp(string, index + 1, n, k);
				string = string.substring(0, string.length() - 1);
			}
		}
	}
}

思路二:对数组{1, 2, 3, ..., n}进行重新排列

以n = 4, k = 14的情况来举例说明该思路。

1 + {2, 3, 4}          6

2 + {1, 3, 4}          6

扫描二维码关注公众号,回复: 3405980 查看本文章

3 + {1, 2, 4}          6

4 + {1, 2, 3}          6

由上述可知,由1开头的排列有6个,由2开头的排列、由3开头的排列、由4开头的排列也均有6个。当我们寻找第14个排列时,势必可以确定第一个数字是3。然后我们将在{1, 2, 4}中寻找第2个排列。

1 + {2, 4}          2

2 + {1, 4}          2

4 + {1, 2}          2

由上述可知,由1开头的排列有2个,由2开头的排列、由4开头的排列也均有2个。当我们寻找第2个排列时,势必可以确定第二个数字是1。然后我们将在{2, 4}中寻找第2个排列。

2 + {4}          1

4 + {2}          1

由上述可知,由2开头的排列有1个,由4开头的排列也有1个。当我们寻找第2个排列时,势必可以确定第三个数字是4。然后我们将在{2}中寻找第1个排列。

由于{2}中只有一个数字,其第一个排列,即第四个数字必定是2。

到此,我们求出n = 4, k = 14的情况的结果是3142。

我们将上述这整一个过程用递归的形式写出来即可。

该算法的时间复杂度和空间复杂度均是O(n)级别的。

JAVA代码:

public class Solution {

	public String getPermutation(int n, int k) {
		int[] array = new int[n];
		for (int i = 0; i < array.length; i++) {
			array[i] = i + 1;
		}
		getPermutation(array, 0, k);
		String result = "";
		for (int i = 0; i < array.length; i++) {
			result += array[i];
		}
		return result;
	}
	
	private void getPermutation(int[] array, int index, int k) {
		if(k == 1) {
			return;
		}
		int i = index;
		int level = factorial(array.length - index - 1);
		for (; i < array.length; i++) {
			if(k - level < 1) {
				break;
			}
			k -= level;
		}
		int temp = array[i];
		for (int j = i - 1; j >= index; j--) {
			array[j + 1] = array[j];
		}
		array[index] = temp;
		getPermutation(array, index + 1, k);
	}

	//to calculate factorial of n
	private int factorial(int n) {
		int result = 1;
		for (int i = 1; i <= n; i++) {
			result *= i;
		}
		return result;
	}
}

LeetCode解题报告:

猜你喜欢

转载自blog.csdn.net/qq_41231926/article/details/82834088