Skip to content

Commit 5f5352d

Browse files
authored
feat(backtracking): all combinations of k numbers out of 1...n (TheAlgorithms#148)
* feat(backtracking): all combinations of k numbers out of 1...n * refactor(backtracking): remove default of 'startCursor' param * docs(backtracking): add docs * refactor(backtracking): move recursive routine in closure
1 parent a4c8d37 commit 5f5352d

2 files changed

Lines changed: 64 additions & 0 deletions

File tree

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* This generates an array of unique sub"sets" (represented by ascendingly sorted subarrays)
3+
* of size k out of n+1 numbers from 1 to n.
4+
*
5+
* By using a backtracking algorithm we can incrementally build sub"sets" while dropping candidates
6+
* that cannot contribute anymore to a valid solution.
7+
* Steps:
8+
* - From the starting number (i.e. "1") generate all combinations of k numbers.
9+
* - Once we got all combinations for the given number we can discard it (“backtracks”)
10+
* and repeat the same process for the next number.
11+
*/
12+
export function generateCombinations(n: number, k: number): number[][] {
13+
let combinationsAcc: number[][] = [];
14+
let currentCombination: number[] = [];
15+
16+
function generateAllCombos(
17+
n: number,
18+
k: number,
19+
startCursor: number
20+
): number[][] {
21+
if (k === 0) {
22+
if (currentCombination.length > 0) {
23+
combinationsAcc.push(currentCombination.slice());
24+
}
25+
return combinationsAcc;
26+
}
27+
28+
const endCursor = n - k + 2;
29+
for (let i = startCursor; i < endCursor; i++) {
30+
currentCombination.push(i);
31+
generateAllCombos(n, k - 1, i + 1);
32+
currentCombination.pop();
33+
}
34+
return combinationsAcc;
35+
}
36+
37+
return generateAllCombos(n, k, 1);
38+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { generateCombinations } from "../all-combinations-of-size-k";
2+
3+
const cases = [
4+
[
5+
3,
6+
2,
7+
[
8+
[1, 2],
9+
[1, 3],
10+
[2, 3],
11+
],
12+
],
13+
[4, 2, [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]],
14+
[0, 0, []],
15+
[2, 3, []],
16+
] as const;
17+
18+
describe("AllCombinationsOfSizeK", () => {
19+
it.each(cases)(
20+
"create all combinations given n=%p and k=%p",
21+
(n, k, expectedCombos) => {
22+
const combinations = generateCombinations(n, k);
23+
expect(combinations).toEqual(expectedCombos);
24+
}
25+
);
26+
});

0 commit comments

Comments
 (0)