题目链接:
示例 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] <= 10
-
nums
中的所有整数 互不相同
解题思路
首先排列是有序的,比如 [1,2,3] 和 [2,1,3] 是两个不同的集合,而在组合里面,这两个集合是一样的。也就是说组合和排列的最大区别就是排列的有序的,集合是无序的。不过,排列中的每个元素只能使用一次,因此可以定义一个 visited 数组或哈希表来记录递归过程中被访问过的元素(注意这不是对同一层的元素进行去重(
C++
class Solution { public: vector<int> path; vector<vector<int>> result; void backTracking(vector<int> nums, vector<bool> visited) { if (path.size() == nums.size()) { result.push_back(path); return; } // 排列问题从头开始遍历 for (int i = 0; i < nums.size(); i++) { if(visited[i] == true) { // 如果该元素已经访问过,则跳过 continue; } path.push_back(nums[i]); visited[i] = true; // 标记 backTracking(nums, visited); path.pop_back(); // 回溯 visited[i] = false; // 回溯 } } vector<vector<int>> permute(vector<int>& nums) { path.clear(); result.clear(); // 用一个数组来记录path中使用过的元素 vector<bool> visited(nums.size(), false); backTracking(nums, visited); return result; } };
JavaScript
let path = []; let result = []; const backTracking = (nums, visited) => { if (path.length === nums.length) { result.push([...path]); return; } for (let i = 0; i < nums.length; i++) { if (visited[i] === true) continue; path.push(nums[i]); visited[i] = true; backTracking(nums, visited); path.pop(); visited[i] = false; } } var permute = function(nums) { let visited = new Array(nums.length); visited.fill(false); path = []; result = []; backTracking(nums, visited); return result; };