Permutations of distinct elements

void permute(int[] nums, List cur, boolean[] used, List> result) {
  if (cur.size() == nums.length) { result.add(new ArrayList<>(cur)); return; }
  for (int i = 0; i < nums.length; i++) {
    if (used[i]) continue;
    used[i] = true; cur.add(nums[i]);
    permute(nums, cur, used, result);
    cur.remove(cur.size() - 1); used[i] = false;
  }
}
Advertisement

Combinations of size k

void combine(int start, int k, List cur, List> result) {
  if (cur.size() == k) { result.add(new ArrayList<>(cur)); return; }
  for (int i = start; i <= n; i++) {
    cur.add(i);
    combine(i + 1, k, cur, result);
    cur.remove(cur.size() - 1);
  }
}
Advertisement

Subsets = power set

void subsets(int[] nums, int start, List cur, List> result) {
  result.add(new ArrayList<>(cur));
  for (int i = start; i < nums.length; i++) {
    cur.add(nums[i]);
    subsets(nums, i + 1, cur, result);
    cur.remove(cur.size() - 1);
  }
}

Handling duplicates

Sort input. Skip i > start && nums[i] == nums[i-1]. Prevents duplicate outputs.