Given an array ​​nums​​ of distinct integers, return all the possible permutations. You can return the answer in any order.

Example 1:

Input: nums = [1,2,3]
Output: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]


Example 2:

Input: nums = [0,1]
Output: [[0,1],[1,0]]


Example 3:

Input: nums = [1]
Output: [[1]]


Constraints:

  • ​1 <= nums.length <= 6​
  • ​-10 <= nums[i] <= 10​
  • All the integers of ​​nums​​ are unique.

全排列。

给一个没有重复元素的数组,请返回这个数组所有可能的全排列。这是backtracking(回溯)类题目的经典题。遇到回溯类型的题,基本思路参见​​这个帖子​​,讲的很好。回溯的题一般都需要

  • 有一个helper函数帮助做backtracking的操作
  • helper函数的返回条件是当前子数组的长度跟数组长度一致
  • 会需要遍历所有可能的选择
  • 做过一选择之后要撤销选择,再去做下一个可行的选择

对于这道题,思路是遍历input数组,如果没有遍历到某个数字,就加入结果集,然后再回溯。因为这道题的input是没有重复数字的,所以其实是不需要去专门检查某一个数字是否有被加入过。而之后的版本二会有出现重复数字,需要额外判断当前数字是否有被遍历过。同时,本题跟subset的区别在于,i指针一定是从0开始,因为找的是排列;而subset找的是子集,所以i需要从start开始,start是一直会变化的。

时间O(n! * n)

空间O(n! * n)

JavaScript实现



1 /**
2 * @param {number[]} nums
3 * @return {number[][]}
4 */
5 var permute = function (nums) {
6 let res = [];
7 if (nums === null || nums.length === 0) return res;
8 helper(res, [], nums);
9 return res;
10 };
11
12 var helper = function (res, list, nums) {
13 if (list.length === nums.length) {
14 res.push(list.slice());
15 return;
16 }
17 for (let i = 0; i < nums.length; i++) {
18 if (list.includes(nums[i])) {
19 continue;
20 }
21 list.push(nums[i]);
22 helper(res, list, nums);
23 list.pop();
24 }
25 }


 

Java实现



1 class Solution {
2 public List<List<Integer>> permute(int[] nums) {
3 List<List<Integer>> res = new ArrayList<>();
4 helper(res, new ArrayList<>(), nums);
5 return res;
6 }
7
8 private void helper(List<List<Integer>> res, List<Integer> list, int[] nums) {
9 if (list.size() == nums.length) {
10 res.add(new ArrayList<>(list));
11 return;
12 }
13 for (int i = 0; i < nums.length; i++) {
14 if (list.contains(nums[i])) {
15 continue;
16 }
17 list.add(nums[i]);
18 helper(res, list, nums);
19 list.remove(list.size() - 1);
20 }
21 }
22 }


 

LeetCode 题目总结