说明:问题描述来源leetcode:
题解1
/**
* @author xin麒
* @date 2022/12/22 12:48
* 给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
* 示例 1: 输入:nums = [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
* 示例 2: 输入:nums = [0,1] 输出:[[0,1],[1,0]]
* 示例 3: 输入:nums = [1] 输出:[[1]]
* 提示: 1 <= nums.length <= 6 -10 <= nums[i] <= 10 nums 中的所有整数 互不相同
*/
public class Solution {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new LinkedList<>();
Set<Integer> set = new HashSet<>();
private int[] nums;
public List<List<Integer>> permute(int[] nums) {
this.nums = nums;
backTracking();
return res;
}
private void backTracking() {
if (path.size() == nums.length) {
res.add(new ArrayList<>(path));
return;
}
for (int i = 0; i < nums.length; i++) {
if (set.contains(i)) continue;
set.add(i);
path.add(nums[i]);
backTracking();
path.remove(path.size() - 1);
set.remove(i);
}
}
}
但是上面对set的操作很繁琐,不断将元素插入和元素删除,实在是操作很繁琐,因此还是不如造一个标记数组来记录每一个索引是否有值被排序,通过下面题解2的 数组boolean[] flag
直接通过地址修改值的操作就减少了很多插入删除的操作,降低了时间复杂度。
题解2
class Solution {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new LinkedList<>();
private int[] nums;
boolean[] flag ;
public List<List<Integer>> permute(int[] nums) {
flag = new boolean[nums.length];
Arrays.fill(flag,true);
this.nums = nums;
backTracking();
return res;
}
private void backTracking() {
if (path.size() == nums.length) {
res.add(new ArrayList<>(path));
return;
}
for (int i = 0; i < nums.length ; i++) {
if ( !flag[i]) continue;
flag[i] = false;
path.add(nums[i]);
backTracking();
path.remove(path.size() - 1);
flag[i] = true;
}
}
}
end