Skip to content

Instantly share code, notes, and snippets.

@yitonghe00
Last active September 5, 2022 02:06
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save yitonghe00/06aa2d74fc38303ec0c306c932277917 to your computer and use it in GitHub Desktop.
Save yitonghe00/06aa2d74fc38303ec0c306c932277917 to your computer and use it in GitHub Desktop.
77. Combinations (https://leetcode.com/problems/combinations/description/): Given two integers n and k, return all possible combinations of k numbers out of 1 ... n.
// Backtracking + DFS solution
// Time: O(2 ^ n), 29ms
// Space: O(n) for there will be only n recursion calls (excluding result), 41.6mb
class Solution {
List<List<Integer>> ans;
public List<List<Integer>> combine(int n, int k) {
ans = new ArrayList<>();
combineR(n, k, 1, new ArrayList<>());
return ans;
}
private void combineR(int n, int k, int index, List<Integer> list) {
// Base case
if(list.size() == k) {
ans.add(new ArrayList<>(list));
return;
}
// Recursion
for(int i = index; i <= n; i++) {
list.add(i);
combineR(n, k, i + 1, list);
list.remove(list.size() - 1);
}
}
}
// Recursion solution: C(n, k) = C(n - 1, k) + C(n - 1, k - 1)
// Time: O(2 ^ n), 4ms
// Space: O(n), 39.2mb
class Solution {
public List<List<Integer>> combine(int n, int k) {
List<List<Integer>> ans;
// Base case 1: k == 0 -> [[]]
if(k == 0) {
ans = new ArrayList();
ans.add(new ArrayList<>());
return ans;
}
// Base case 2: n == k -> [[1, 2, .., n]]
if(n == k) {
ans = new ArrayList();
List<Integer> list = new ArrayList<>();
for(int i = 1; i <= n; i++) list.add(i);
ans.add(list);
return ans;
}
ans = combine(n - 1, k);
for(List<Integer> p : combine(n - 1, k - 1)) {
p.add(n);
ans.add(p);
}
return ans;
}
}
// DP solution: C(n, k) = C(n - 1, k) + C(n - 1, k - 1)
// Time: O(n * k * C) for n * k table, every cell takes C time to concatenate, where C is the combination, 106ms
// Space: O(n * k ^ 2 * C) for there will be a n * k table, where each cell is at most C arrays with length of O(k)
class Solution {
public List<List<Integer>> combine(int n, int k) {
// Define the table
List<List<Integer>>[][] table = new List[n + 1][k + 1];
// Base case
for(int j = 0; j <= k; j++) {
table[0][j] = new ArrayList<>();
table[0][j].add(new ArrayList<>());
}
for(int i = 0; i <= n; i++) {
table[i][0] = new ArrayList<>();
table[i][0].add(new ArrayList<>());
}
// Fill the table
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= i && j <= k; j++) {
table[i][j] = new ArrayList<>();
if(table[i - 1][j] != null) {
for(List<Integer> list : table[i - 1][j]) {
if(list.size() == 0) continue;
table[i][j].add(list);
}
}
for(List<Integer> list : table[i - 1][j - 1]) {
List<Integer> newList = new ArrayList<>(list);
newList.add(i);
table[i][j].add(newList);
}
}
}
// Return the bottom right cell
return table[n][k];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment