Backtracking

Backtracking algorithms heavily use DFS1 to enumerate all the possible solutions to a problem. These candidates are expressed as the nodes of a tree structure, which is the potential Search Tree [1].

Examples

The Subsets is a classic problem suitable for Backtracking.

At each call, we can decide whether or not to include the current element. This decision requires two different function calls that will derive the following Search Tree from the input [1, 2, 3].

Gstart*a11start--a1b1start--b1a22a1--a2b2a1--b2c22b1--c2d2b1--d2a33a2--a3b3a2--b3c33b2--c3d3b2--d3e33c2--e3f3c2--f3g33d2--g3h3d2--h3

If we collect the results of the 8 leaf nodes, we will get all our subsets.

Analyze the Complexity

The Time Complexity is proportional to the number of nodes in the Search Tree, multiplied by the amount of work we do in each call.

We can use the formula to derive the number of nodes. If we apply this formula to the previous problem, we get and , where the height is actually the number of nodes in the input. Plus, we need to consider the work we do to append the solutions to the final result list, which is an additional time. This would make the entire complexity to .

The Space Complexity is proportional to the height of the Search Tree. In fact, once we reach a leaf node, we simply terminate our search and go back to the parent nodes.

References

1

We already saw the DFS algorithm applied to both Trees and Graphs.