90. Subsets II

#include <stdlib.h>
#include <string.h>

static int cmp(const void *a, const void *b) {
  int x = *(const int *)a, y = *(const int *)b;
  return (x > y) - (x < y);
}

static void backtrack(int *nums, int n, int idx, int *cur, int curSize,
                      int **result, int *returnSize, int *colSizes) {
  if (idx == n) {
    result[*returnSize] = malloc(curSize * sizeof(int));
    memcpy(result[*returnSize], cur, curSize * sizeof(int));
    colSizes[(*returnSize)++] = curSize;
    return;
  }

  cur[curSize] = nums[idx];
  backtrack(nums, n, idx + 1, cur, curSize + 1, result, returnSize, colSizes);

  int i = idx + 1;
  while (i < n && nums[idx] == nums[i])
    i++;

  backtrack(nums, n, i, cur, curSize, result, returnSize, colSizes);
}

int **subsetsWithDup(int *nums, int numsSize, int *returnSize,
                     int **returnColumnSizes) {
  int total = 1 << numsSize; // upper bound, reached only without duplicates
  int **result = malloc(total * sizeof(int *));
  *returnColumnSizes = malloc(total * sizeof(int));
  *returnSize = 0;
  qsort(nums, numsSize, sizeof(int), cmp);
  int cur[numsSize > 0 ? numsSize : 1];
  backtrack(nums, numsSize, 0, cur, 0, result, returnSize, *returnColumnSizes);
  return result;
}
#include <algorithm>
#include <vector>

using namespace std;

class Solution {
public:
  vector<vector<int>> subsetsWithDup(vector<int> &nums) {
    vector<vector<int>> result;
    vector<int> cur;
    sort(nums.begin(), nums.end());
    backtrack(nums, 0, cur, result);
    return result;
  }

  void backtrack(vector<int> &nums, int idx, vector<int> &cur,
                 vector<vector<int>> &result) {
    if (idx == nums.size()) {
      result.push_back(cur);
      return;
    }

    cur.push_back(nums[idx]);
    backtrack(nums, idx + 1, cur, result);
    cur.pop_back();

    int i = idx + 1;
    while (i < nums.size() && nums[idx] == nums[i])
      i++;

    backtrack(nums, i, cur, result);
  }
};
package backtracking

import "sort"

func subsetsWithDup(nums []int) [][]int {
    var result [][]int
    var cur []int
    sort.Ints(nums)

    var backtrack func(idx int)
    backtrack = func(idx int) {
        if idx == len(nums) {
            result = append(result, append([]int(nil), cur...))
            return
        }

        cur = append(cur, nums[idx])
        backtrack(idx + 1)
        cur = cur[:len(cur)-1]

        i := idx + 1
        for i < len(nums) && nums[idx] == nums[i] {
            i++
        }

        backtrack(i)
    }

    backtrack(0)
    return result
}
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

class Solution {
    public List<List<Integer>> subsetsWithDup(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
        Arrays.sort(nums);
        backtrack(nums, 0, new ArrayList<>(), result);
        return result;
    }

    private void backtrack(int[] nums, int idx, List<Integer> cur, List<List<Integer>> result) {
        if (idx == nums.length) {
            result.add(new ArrayList<>(cur));
            return;
        }

        cur.add(nums[idx]);
        backtrack(nums, idx + 1, cur, result);
        cur.remove(cur.size() - 1);

        int i = idx + 1;
        while (i < nums.length && nums[idx] == nums[i]) {
            i++;
        }

        backtrack(nums, i, cur, result);
    }
}
/**
 * @param {number[]} nums
 * @return {number[][]}
 */
var subsetsWithDup = function (nums) {
  const result = [];
  const cur = [];
  nums.sort((a, b) => a - b);

  const backtrack = (idx) => {
    if (idx === nums.length) {
      result.push([...cur]);
      return;
    }

    cur.push(nums[idx]);
    backtrack(idx + 1);
    cur.pop();

    let i = idx + 1;
    while (i < nums.length && nums[idx] === nums[i]) i++;

    backtrack(i);
  };

  backtrack(0);
  return result;
};
from typing import List


class Solution:
    def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
        result: List[List[int]] = []
        cur: List[int] = []
        nums.sort()

        def backtrack(idx: int) -> None:
            if idx == len(nums):
                result.append(cur[:])
                return

            cur.append(nums[idx])
            backtrack(idx + 1)
            cur.pop()

            i = idx + 1
            while i < len(nums) and nums[idx] == nums[i]:
                i += 1

            backtrack(i)

        backtrack(0)
        return result
impl Solution {
    pub fn subsets_with_dup(mut nums: Vec<i32>) -> Vec<Vec<i32>> {
        let mut result = Vec::new();
        let mut cur = Vec::with_capacity(nums.len());
        nums.sort_unstable();
        Self::backtrack(&nums, 0, &mut cur, &mut result);
        result
    }

    fn backtrack(nums: &[i32], idx: usize, cur: &mut Vec<i32>, result: &mut Vec<Vec<i32>>) {
        if idx == nums.len() {
            result.push(cur.clone());
            return;
        }

        cur.push(nums[idx]);
        Self::backtrack(nums, idx + 1, cur, result);
        cur.pop();

        let mut i = idx + 1;
        while i < nums.len() && nums[idx] == nums[i] {
            i += 1;
        }

        Self::backtrack(nums, i, cur, result);
    }
}