JAVA练习328- 全排列
题目概览
给定一个不含重复数字的数组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] <= 10nums中的所有整数互不相同
来源:46. 全排列 - 力扣(LeetCode)
解题分析
方法:回溯
以 [1,2,3] 为例,它的排列可以看做:
先固定 1,然后固定 2,得到 [1,2,3],然后不固定 2,交换 3 和 2 得到 [1,3,2],
然后不固定 1,交换 1 和 2,
然后固定 2,再固定 1,得到 [ 2,1,3],然后不固定 1,交换 3 和 1 得到 [2,3,1],
然后不固定 2,交换 1 和 3,
然后固定 2,再固定 1,得到 [ 3,2,1],然后不固定 2,交换 2 和 1 得到 [3,1,2]。
令当前索引为 i,那么这过程就可以看做依次 i 和 [ i, n-1 ] 的数做交换,然后递归 i + 1,继续重复直到遍历 i = n,得到结果后,将 i 和 [ i, n-1 ] 的数交换回来,继续遍历,最后得到答案。
时间复杂度:O(n×n!)
空间复杂度:O(n)
class Solution { public List<List<Integer>> permute(int[] nums) { List<Integer> list = new ArrayList<>(); for (int num: nums) { list.add(num); } List<List<Integer>> result = new ArrayList<>(); backTracking(nums.length, result, list, 0); return result; } public void backTracking(int n, List<List<Integer>> result, List<Integer> nums, int index) { if (index == n) { result.add(new ArrayList<>(nums)); return; } for (int i = index; i < n; ++i) { Collections.swap(nums, index, i); backTracking(n, result, nums, index + 1); Collections.swap(nums, index, i); } } }