题目:
Given a collection of distinct numbers, return all possible permutations.
For example,
[1,2,3]
have the following permutations:
[1,2,3]
, [1,3,2]
, [2,1,3]
, [2,3,1]
, [3,1,2]
, and [3,2,1]
.
需要实现的函数:
public class Solution {
public List<List<Integer>> permute(int[] nums) {
}
}
分析:
依照递归的三个步骤:
(1). 确定 base case
对于任意一个permutation的形式 cur,当 cur中元素的个数 = nums.length,找到一个正确的 permutation;
(2). 找到 recursion rule
锁定第一个数,排列剩余的 nums.length-1 个数;
— — 锁定第二个数,排列剩余的 nums.length-2 个数;
— — 锁定第三个数,排列剩余的 nums.length-3 个数;
(3). 确定递归函数的参数
需要提供排列数字的数组 int[] nums;
需要记录最后所有permutations的参数 List<List<Integer>> results;
需要记录当前permutationd的参数 List<Integer> cur;
代码:
public class LeetCode46 {
public static void main(String[] args) {
int[] nums = {1, 2, 3};
System.out.println(permute(nums));
}
public static List<List<Integer>> permute(int[] nums) {
List<List<Integer>> results = new ArrayList<List<Integer>>();
permute(results, new ArrayList<Integer>(), nums);
return results;
}
private static void permute(List<List<Integer>> results, List<Integer> cur, int[] nums) {
if (cur.size() == nums.length) {
results.add(new ArrayList<Integer>(cur));
return;
}
for (int i = 0; i < nums.length; i++) {
if (!cur.contains(nums[i])) {
cur.add(nums[i]);
permute(results, cur, nums);
cur.remove(cur.size()-1);
}
}
}
}
优化:
上述代码中,每一次递归中的for循环都是用 i = 0 开始遍历,并且 cur.contains(nums[i])的时间复杂度为O(n),有优化的空间。
递归函数中,新增一个参数 int index,记录 for 循环中开始遍历的位置:如果 cur 中已经包含 nums[index]了,说明 for循环 只需要从 index+1 开始遍历。
如果 i > index && i < nums.length,cur 中已经有了 nums[i],需要将 nums[i] 与 nums[index] swap,子递归就不会重复选择 nums[i]。
代码:
public static List<List<Integer>> permute(int[] nums) {
List<List<Integer>> results = new ArrayList<List<Integer>>();
permute(results, new ArrayList<Integer>(), nums, 0);
return results;
}
private static void permute(List<List<Integer>> results, List<Integer> cur, int[] nums, int index) {
if (cur.size() == nums.length) {
results.add(new ArrayList<Integer>(cur));
return;
}
for (int i = index; i < nums.length; i++) {
cur.add(nums[i]);
swap(nums, index, i);
permute(results, cur, nums, index+1);
swap(nums, index, i);
cur.remove(cur.size()-1);
}
}
private static void swap(int[] nums, int i, int j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}