Permutations II

medium array backtracking

Problem

Given an integer array nums that might contain duplicates, return all possible unique permutations in any order.

Inputnums = [1, 1, 2]
Output[[1,1,2],[1,2,1],[2,1,1]]
Three unique orderings. Sort first, then skip nums[i] when it equals nums[i-1] and i-1 is unused at this level.

def permute_unique(nums):
    nums.sort()
    out, cur, used = [], [], [False] * len(nums)
    def dfs():
        if len(cur) == len(nums):
            out.append(cur[:]); return
        for i in range(len(nums)):
            if used[i]: continue
            if i > 0 and nums[i] == nums[i - 1] and not used[i - 1]:
                continue
            used[i] = True; cur.append(nums[i])
            dfs()
            cur.pop(); used[i] = False
    dfs()
    return out
function permuteUnique(nums) {
  nums.sort((a, b) => a - b);
  const out = [], cur = [], used = new Array(nums.length).fill(false);
  function dfs() {
    if (cur.length === nums.length) { out.push(cur.slice()); return; }
    for (let i = 0; i < nums.length; i++) {
      if (used[i]) continue;
      if (i > 0 && nums[i] === nums[i - 1] && !used[i - 1]) continue;
      used[i] = true; cur.push(nums[i]);
      dfs();
      cur.pop(); used[i] = false;
    }
  }
  dfs();
  return out;
}
class Solution {
    public List<List<Integer>> permuteUnique(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> out = new ArrayList<>();
        boolean[] used = new boolean[nums.length];
        dfs(nums, used, new ArrayList<>(), out);
        return out;
    }
    private void dfs(int[] nums, boolean[] used, List<Integer> cur, List<List<Integer>> out) {
        if (cur.size() == nums.length) { out.add(new ArrayList<>(cur)); return; }
        for (int i = 0; i < nums.length; i++) {
            if (used[i]) continue;
            if (i > 0 && nums[i] == nums[i - 1] && !used[i - 1]) continue;
            used[i] = true; cur.add(nums[i]);
            dfs(nums, used, cur, out);
            cur.remove(cur.size() - 1); used[i] = false;
        }
    }
}
class Solution {
public:
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        vector<vector<int>> out;
        vector<int> cur;
        vector<bool> used(nums.size(), false);
        dfs(nums, used, cur, out);
        return out;
    }
    void dfs(vector<int>& nums, vector<bool>& used, vector<int>& cur, vector<vector<int>>& out) {
        if (cur.size() == nums.size()) { out.push_back(cur); return; }
        for (int i = 0; i < (int)nums.size(); i++) {
            if (used[i]) continue;
            if (i > 0 && nums[i] == nums[i - 1] && !used[i - 1]) continue;
            used[i] = true; cur.push_back(nums[i]);
            dfs(nums, used, cur, out);
            cur.pop_back(); used[i] = false;
        }
    }
};
Time: O(n · n!) Space: O(n)