地址:https://leetcode-cn.com/problems/permutations/
我写的题解地址:https://leetcode-cn.com/problems/permutations/solution/hui-su-suan-fa-python-dai-ma-java-dai-ma-by-liweiw/
Java 代码:
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
public class Solution {
// 时间复杂度: O(n^n)
// 空间复杂度: O(n)
public List<List<Integer>> permute(int[] nums) {
int len = nums.length;
List<List<Integer>> res = new ArrayList<>(len);
if (len == 0) {
return res;
}
boolean[] used = new boolean[len];
Deque<Integer> stack = new ArrayDeque<>(len);
backtrack(nums, 0, len, used, stack, res);
return res;
}
private void backtrack(int[] nums, int index, int len, boolean[] used, Deque<Integer> stack, List<List<Integer>> res) {
if (index == len) {
res.add(new ArrayList<>(stack));
return;
}
for (int i = 0; i < len; i++) {
if (!used[i]) {
used[i] = true;
stack.addLast(nums[i]);
backtrack(nums, index + 1, len, used, stack, res);
stack.removeLast();
used[i] = false;
}
}
}
}
复杂度分析:
- 时间复杂度:
- 空间复杂度:
说明:
1、这里的 used
数组记录了当前所在结点的状态;
2、used
数组可以使用哈希表或者“位掩码”替代。
Java 代码:
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Solution {
public List<List<Integer>> permute(int[] nums) {
int len = nums.length;
List<List<Integer>> res = new ArrayList<>(len);
if (len == 0) {
return res;
}
// 使用哈希表检测一个数字是否使用过
Set<Integer> used = new HashSet<>(len);
Deque<Integer> stack = new ArrayDeque<>(len);
backtrack(nums, 0, len, used, stack, res);
return res;
}
private void backtrack(int[] nums, int index, int len, Set<Integer> used, Deque<Integer> stack, List<List<Integer>> res) {
if (index == len) {
res.add(new ArrayList<>(stack));
return;
}
for (int i = 0; i < len; i++) {
if (!used.contains(i)) {
used.add(i);
stack.addLast(nums[i]);
backtrack(nums, index + 1, len, used, stack, res);
stack.removeLast();
used.remove(i);
}
}
}
}
Java 代码:
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
public class Solution {
public List<List<Integer>> permute(int[] nums) {
int len = nums.length;
List<List<Integer>> res = new ArrayList<>(len);
if (len == 0) {
return res;
}
int hash = 0;
Deque<Integer> stack = new ArrayDeque<>(len);
backtracking(nums, 0, hash, stack, len, res);
return res;
}
private void backtracking(int[] nums, int index, int hash, Deque<Integer> stack, int len, List<List<Integer>> res) {
if (index == len) {
res.add(new ArrayList<>(stack));
return;
}
for (int i = 0; i < len; i++) {
if (((hash >> i) & 1) == 0) {
stack.addLast(nums[i]);
hash ^= (1 << i);
backtracking(nums, index + 1, hash, stack, len, res);
hash ^= (1 << i);
stack.removeLast();
}
}
}
}