一、不重复全排列
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
https://leetcode.cn/problems/permutations/description/
1、dfs + boolean[]
通过boolean[]记录
public List<List<Integer>> permute(int[] nums) {
boolean[] used = new boolean[nums.length];
return dfs(nums, used, new ArrayList<>(), new ArrayList<>());
}
private List<List<Integer>> dfs(int[] nums, boolean[] used, List<Integer> part, List<List<Integer>> ans) {
if (part.size() == nums.length) {
ans.add(new ArrayList<>(part));
}
for (int i = 0; i < nums.length; i++) {
if (used[i]) {
continue;
}
part.add(nums[i]);
used[i] = true;
dfs(nums, used, part, ans);
part.remove(part.size() - 1);
used[i] = false;
}
return ans;
}
2、dfs + swap
较一快一丢丢丢,但是我觉得比一难理解很多
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
dfs(nums, 0, res);
return res;
}
public void dfs(int[] nums, int index, List<List<Integer>> res) {
if (index == nums.length) {
ArrayList<Integer> list = new ArrayList<>();
for (int num : nums) {
list.add(num);
}
res.add(list);
return res;
}
for (int i = index; i < nums.length; i++) {
swap(nums, index, i);
recursiveProgress(nums, index + 1, res);
swap(nums, index, i);
}
return res;
}
public void swap(int[] arr, int i, int j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
二、重复全排列
给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。
https://leetcode.cn/problems/permutations-ii/description/
1、dfs + boolean[] + sort
public List<List<Integer>> permuteUnique(int[] nums) {
Arrays.sort(nums);
return backtrack(nums, new boolean[nums.length], 0, new ArrayList<>(), new ArrayList<>());
}
public List<List<Integer>> backtrack(int[] nums, boolean[] used, int idx, List<Integer> part, List<List<Integer>> ans) {
if (idx == nums.length) {
ans.add(new ArrayList<>(part));
return ans;
}
for (int i = 0; i < nums.length; ++i) {
if (vis[i] || (i > 0 && nums[i] == nums[i - 1] && !vis[i - 1])) {
continue;
}
part.add(nums[i]);
vis[i] = true;
backtrack(nums, used, idx + 1, part, ans);
vis[i] = false;
part.remove(idx);
}
return ans;
}
2、dfs + swap + flag
public List<List<Integer>> permuteUnique(int[] nums) {
return dfs(nums, 0, new ArrayList<>());
}
private List<List<Integer>> dfs(int[] nums, int idx, List<List<Integer>> ans) {
if (idx == nums.length) {
List<Integer> part = new ArrayList<>();
for (int num : nums) {
part.add(num);
}
ans.add(part);
}
for (int i = idx; i < nums.length; i++) {
boolean flag = false;
for (int j = idx; j < i; j++) {
if (nums[j] == nums[i]) {
flag = true;
break;
}
}
if (flag) {
continue;
}
swap(nums, i, idx);
dfs(nums, idx + 1, ans);
swap(nums, i, idx);
}
return ans;
}
三、排列计数
给定 n 和 k,返回第 k 个排列。
https://leetcode.cn/problems/permutation-sequence/description/
public class Solution{
boolean[] used;
int[] nums;
int total = 0;
int[] factor;
public String getPermutation(int n, int k) {
init(n, k);
List<Integer> part = new ArrayList<>();
find(0, n, k, part);
return part.stream().map(e -> e.toString()).collect(Collectors.joining());
}
private void init(int n, int k) {
factor = new int[n + 1];
factor[0] = 1;
for (int i = 1; i <= n; i++) {
factor[i] = factor[i - 1] * i;
}
this.nums = IntStream.range(1, n + 1).toArray();
this.used = new boolean[n];
}
private void find(int depth, int n, int k, List<Integer> part) {
if (part.size() == nums.length) {
++total;
return;
}
for (int i = 0; i < nums.length; i++) {
int cnt = factor[n - depth - 1];
if (used[i]) {
continue;
}
if (total + cnt < k) {
total += cnt;
continue;
}
part.add(nums[i]);
used[i] = true;
find(depth + 1, n, k, part);
if (total == k) {
return;
}
part.remove(part.size() - 1);
used[i] = false;
}
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。