[LeetCode] 46. Permutations

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.

全排列。

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

这是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 题目总结

posted @ 2020-03-05 08:57  CNoodle  阅读(454)  评论(0编辑  收藏  举报