全排列
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
示例:
输入 :nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
解题思路
- 1、使用回溯算法来生成所有可能的全排列。
- 2、从第一个位置开始,依次将每个数字放入当前位置,并递归生成下一个位置的排列。
- 3、当所有位置都填满时,将当前排列加入结果集。
具体步骤
- 1、初始化一个空列表 result,用于存储所有可能的全排列。
- 2、编写一个递归函数 backtrack,该函数接受当前正在处理的子数组 nums、 以及当前正在构建的排列 tempList。
- 3、在 backtrack 中,如果 current 的长度等于 nums 的长度,
- 说明已经构建出了一个完整的排列,将其加入到 result 中。
- 4、否则,遍历数组 nums,对于每个未被使用过的数字,将其添加到 tempList 中,并递归调用 backtrack 处理剩余的子数组。
- 5、在递归调用完成后,要将刚刚添加到 tempList 中的数字从中删除,以便后续使用。
Java实现
java
public class Permutation {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> result = new ArrayList<>();
backtrack(nums, new ArrayList<>(), result);
return result;
}
private void backtrack(int[] nums, List<Integer> tempList, List<List<Integer>> result) {
if (tempList.size() == nums.length) {
result.add(new ArrayList<>(tempList));
} else {
for (int i = 0; i < nums.length; i++) {
if (tempList.contains(nums[i])) continue; // element already exists, skip
tempList.add(nums[i]);
backtrack(nums, tempList, result);
//回溯一层后,对应移除上一层的末尾元素
tempList.remove(tempList.size() - 1);
}
}
}
public static void main(String[] args) {
Permutation permutation = new Permutation();
// Test Case 1
int[] nums1 = {1, 2, 3};
List<List<Integer>> result1 = permutation.permute(nums1);
System.out.println("Test Case 1:");
printResult(result1);
// Test Case 2
int[] nums2 = {0, 1};
List<List<Integer>> result2 = permutation.permute(nums2);
System.out.println("Test Case 2:");
printResult(result2);
}
private static void printResult(List<List<Integer>> result) {
for (List<Integer> list : result) {
System.out.println(list);
}
System.out.println();
}
}
时间空间复杂度
-
时间复杂度:O(N!),其中N是数组nums的长度。因为生成全排列的数量是N的阶乘。
-
空间复杂度:O(N!),存储所有可能的全排列。