47. 全排列 II

47. 全排列 II

题目链接:47. 全排列 II(中等)

给定一个可包含重复数字的序列 nums按任意顺序 返回所有不重复的全排列。

示例 1:

输入:nums = [1,1,2]
输出:
[[1,1,2],
[1,2,1],
[2,1,1]]

示例 2:

输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

提示:

  • 1 <= nums.length <= 8

  • -10 <= nums[i] <= 10

解题思路

这道题与46. 全排列 的不同就是需要对排列进行同一层的去重,去重的方法可以参考491. 递增子序列 (这是不需要提前对nums进行排序)或者40. 组合总和 II (这需要提前对nums进行排序)。

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;
        }
        // used是记录本层元素是否重复使用,新的一层used都会重新定义(清空),所以要知道used只负责本层
        // 题目中说数值范围是[-10,10]
        int used[21] = {0};
        for (int i = 0; i < nums.size(); i++) {
            // 判断当前元素在本层是否已经使用过
            // +10是为了将[-10,0]中的值变为正数
            if (used[10 + nums[i]] == 1) continue;
            // 判断当前元素在递归中是否已经使用过
            if (visited[i] == true) continue;
            path.push_back(nums[i]);
            visited[i] = true;
            used[10 + nums[i]] = 1; // 不用回溯
            backTracking(nums, visited);
            path.pop_back();  // 回溯
            visited[i] = false; // 回溯
        }
    }
​
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        path.clear();
        result.clear();
        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;
    }
​
    let used = new Array(21);
    used.fill(0);
    for (let i = 0; i < nums.length; i++) {
        if (used[nums[i] + 10] === 1) continue;
        if (visited[i] === true) continue;
        path.push(nums[i]);
        used[nums[i] + 10] = 1;
        visited[i] = true;
        backTracking(nums, visited);
        path.pop();
        visited[i] = false;
    }
}
​
var permuteUnique = function(nums) {
    let visited = new Array(nums.length);
    visited.fill(false);
    path = [];
    result = [];
    backTracking(nums, visited);
    return result;
};

 

原文地址:https://www.cnblogs.com/wltree/p/15741422.html