排列序列
难度:
标签:
题目描述
给出集合 [1,2,3,...,n]
,其所有元素共有 n!
种排列。
按大小顺序列出所有排列情况,并一一标记,当 n = 3
时, 所有排列如下:
"123"
"132"
"213"
"231"
"312"
"321"
给定 n
和 k
,返回第 k
个排列。
示例 1:
输入:n = 3, k = 3 输出:"213"
示例 2:
输入:n = 4, k = 9 输出:"2314"
示例 3:
输入:n = 3, k = 1 输出:"123"
提示:
1 <= n <= 9
1 <= k <= n!
代码结果
运行时间: 43 ms, 内存: 15.9 MB
/*
* 题目思路:
* 1. 使用 Stream API 初始化候选数字的列表。
* 2. 使用循环选择每一位数字,按照与常规 Java 版本相同的逻辑。
* 3. 使用流操作来生成结果字符串。
*/
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Solution {
public String getPermutation(int n, int k) {
int[] factorial = new int[n];
List<Integer> numbers = IntStream.rangeClosed(1, n).boxed().collect(Collectors.toList());
StringBuilder result = new StringBuilder();
// 计算阶乘数组
factorial[0] = 1;
for (int i = 1; i < n; i++) {
factorial[i] = factorial[i - 1] * i;
}
k--;
for (int i = n; i > 0; i--) {
int index = k / factorial[i - 1];
result.append(numbers.remove(index));
k %= factorial[i - 1];
}
return result.toString();
}
}
解释
方法:
这个题解使用了数学推导的方法,通过计算阶乘数组和确定每一位数字来生成第k个排列。具体步骤如下:
1. 计算阶乘数组 factorial,其中 factorial[i] 表示 i 的阶乘,用于后续计算每一位数字的索引。
2. 初始化剩余数字列表 nums,包含从 1 到 n 的所有数字。
3. 初始化结果字符串 result,用于存储最终的排列结果。
4. 从最高位开始,通过 k 除以 factorial[i] 的商确定每一位的数字,并将对应的数字从 nums 中移除,同时更新 k 的值。
5. 重复步骤4,直到确定了所有位的数字。
6. 返回生成的排列结果 result。
时间复杂度:
O(n^2)
空间复杂度:
O(n)
代码细节讲解
🦆
在题解中,如何确定每一位数字的具体值?请详细解释这个过程。
▷🦆
为什么在计算每一位数字时需要将 k 减去 'index * factorial[i]',这样做的目的是什么?
▷🦆
题解中提到将数字从剩余数字列表 nums 中移除,这个操作为何重要,它对生成正确的排列结果有什么影响?
▷🦆
题解中使用了阶乘数组 factorial,这种预处理的意义何在?
▷相关问题
下一个排列
整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。
- 例如,
arr = [1,2,3]
,以下这些都可以视作arr
的排列:[1,2,3]
、[1,3,2]
、[3,1,2]
、[2,3,1]
。
整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地,如果数组的所有排列根据其字典顺序从小到大排列在一个容器中,那么数组的 下一个排列 就是在这个有序容器中排在它后面的那个排列。如果不存在下一个更大的排列,那么这个数组必须重排为字典序最小的排列(即,其元素按升序排列)。
- 例如,
arr = [1,2,3]
的下一个排列是[1,3,2]
。 - 类似地,
arr = [2,3,1]
的下一个排列是[3,1,2]
。 - 而
arr = [3,2,1]
的下一个排列是[1,2,3]
,因为[3,2,1]
不存在一个字典序更大的排列。
给你一个整数数组 nums
,找出 nums
的下一个排列。
必须 原地 修改,只允许使用额外常数空间。
示例 1:
输入:nums = [1,2,3] 输出:[1,3,2]
示例 2:
输入:nums = [3,2,1] 输出:[1,2,3]
示例 3:
输入:nums = [1,1,5] 输出:[1,5,1]
提示:
1 <= nums.length <= 100
0 <= nums[i] <= 100