Medium
Given a collection of distinct integers, return all possible permutations.
Example:
Input: [1,2,3]
Output:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
解法:(回溯)
本题要求生成全排列,那么看看我们能找到什么规律。以[1,2,3]为例,全排列是
[1,2,3]
[1,3,2]
[2,1,3]
[2,3,1]
[3,1,2]
[3,2,1]
如果从纵向看这些全排列,直觉上能发现第一列就是分别以原数组的第0位,第1位和第2位的数字作为每个全排列的开头,然后其余的数字放到后面并通过一次交换位置形成两组新的全排列。
那么如果数组中的数字多余3个呢?比如[1,2,3,4],规律还成立吗?
[1,2,3,4]
[1,2,4,3]
[1,3,2,4]
[1,3,4,2]
[1,4,2,3]
[1,4,3,2]
[2,1,3,4]
[2,1,4,3]
[2,3,1,4]
[2,3,4,1]
[3,1,2,4]
[3,1,4,2]
[3,4,1,2]
[3,4,2,1]
[4,1,2,3]
[4,1,3,2]
[4,2,1,3]
[4,2,3,1]
[4,3,1,2]
[4,3,2,1]
可以看出来,第一列依然符合之前的规律,如果把第一列遮挡住,第2,3,4列其实就是在重复刚才[1, 2, 3]的规律。只不过这次数组里的数字是[2,3,4]罢了。
有了这个规律,我们就可以写出如下算法:
public static List<List<Integer>> permute(int[] nums) {
List<Integer> list = new ArrayList<>();
for(int i : nums) {
list.add(i) ;
}
List<List<Integer>> res = new ArrayList<>();
backTrack(nums.length, list, res, 0);
return res;
}
private static void backTrack(int max_len, List<Integer> currList, List<List<Integer>> res, int first) {
if(first == max_len) {
res.add(new ArrayList<>(currList)) ;
// for(int num : currList){
// System.out.print(num+" ");
// }
// System.out.println() ;
}
for(int i=first; i<max_len; i++) {
Collections.swap(currList, first, i);
backTrack(max_len, currList, res, first + 1) ;
Collections.swap(currList, first, i);
}
}