The Technical Interview Guide to Backtracking
By: Jennifer Fu
Tags: Sudoku, Combination, Interview, Coding Interview, Programming

Permutations, Combinations, Subsets, and Variations

Permutations

A permutation of a set is an arrangement of its members into a sequence. The order of selection matters. To use [1, 2, 3] as an example, its permutations are [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] .

Here is the backtracking algorithm to print out permutations from number choices:

At line 28, we try the next candidate using the original start value, which will use every candidate. To prevent the same choice being used more than once, line 23 ensures that the number has not been used yet.

These are verifying tests:

Permutation Count

Obviously, we can use dynamic programming for the optimal solution if the problem only asks for the permutation count.

Here is the dynamic programming algorithm to print out permutation count from number choices:

These are verifying tests:

Not surprisingly, the permutation count is the factorial number.

Combinations

A combination is a selection of items from a collection. The order of selection does not matter. We can use a similar program to calculate the combinations. [1, 2, 3] 's combinations are [[1, 2, 3]] .

Here is the backtracking algorithm to print out combinations from number choices:

At line 26, we try the next candidate using i + 1, which will start with an unused candidate.

These are verifying tests:

It seems meaningless to print out the same choice as the result. However, this algorithm is the foundation for many combination variations. The takeaway is the next candidate index. If the candidate cannot be reused, use the index, i + 1. Otherwise, use the index, i.

Subsets

A set A is a subset of a set B if all elements of A are also elements of B. It is possible for A and B to be equal. [1, 2, 3] has subsets [[],[1],[1,2],[1,2,3],[1,3],[2],[2,3],[3]] .

Here is the backtracking algorithm to print out subsets from number choices:

These are verifying tests:

Permutation Subsets

The subsets are combinations. How about treat a subset’s permutations differently? Use [1, 2] as an example:

Its subsets are [[],[1],[1,2],[2]] .

. Its permutation subsets are [[],[1],[1,2],[2],[2,1]] .

To generate permutation subsets, each backtracking call needs to start from the first choice. Also, the used choice can not be reused.

Here is the algorithm for permutation subsets:

Lines 24 - 26 backtrack from unused choices.

These are verifying tests:

Permutation Subsets Not Unique

We have assumed that each number choice is a unique natural number. What if the number choices are not unique?

For example, [1,2,1] ’s permutation subsets are [[],[1],[1,1],[1,1,2],[1,2],[1,2,1],[2],[2,1],[2,1,1]] .

In this case, we need to sort the choices to make sure the same numbers are next to each other. Therefore, we can avoid putting the same number at the same position multiple times.

Here is the algorithm for permutation subsets with numbers that are not unique:

Line 46 sorts the choices.

Lines 32 - 37 skip the choices that are the same as the previous ones.

These are verifying tests:

Combinational sum with no duplicates

Provided with an array of distinct natural number choices and a target value, we can use a combination algorithm to find unique combinations that sum up to the target value. Each number choice can be used at most once. For example, the choices are [1, 2, 3, 4] and the target is 5. The unique combinations are [[1, 4], [2, 3]] .

The backtracking algorithm for no-duplicate combinations is written as follows:

These are verifying tests:

Combinational sum with duplicates

We change the condition to allow each number choice to be used as many times as possible. For the same example of choices [1, 2, 3, 4] and the target of 5. The allow-duplicate combinations are [[1, 1, 1, 1, 1], [1, 1, 1, 2], [1, 1, 3], [1, 2, 2], [1, 4], [2, 3]] .

The backtracking algorithm for allow-duplicate combinations is written as follows:

The allow-duplicate combinations code is almost identical to no-duplicate combinations, except at line 31 where the next candidate uses the same index, i.

With this small tweak, the verifying tests output allow-duplicate combinations: