@@ -24,14 +24,14 @@ It stops evaluating a path as soon as some of the conditions are broken and move
2424However, it an only be applied if a quick test can be run to tell if a candidate will contribute to a valid solution.
2525****
2626
27- == How to develop Backtracking algorithms?
27+ == How to develop backtracking algorithms?
2828
2929Backtracking algorithms can be tricky to get right or reason about but we are going to follow this recipe to make it easier.
3030
3131.Steps to create backtracking algorithms
3232. Iterate through all the elements in the input
3333. Make a change
34- . Call recursive function
34+ . Recursive function moving to the next element
3535. Test if the current change is a solution
3636. Revert back the change (backtracking)
3737
@@ -43,7 +43,7 @@ Let's do an exercise to explain better how backtracking works.
4343
4444> Return all the permutations (without repetitions) of a given word.
4545
46- For instace, if are given the word `art` we can have the following permutions
46+ For instace, if you are given the word `art` these are the possible permutations:
4747
4848----
4949[ [ 'art' ],
@@ -54,23 +54,39 @@ For instace, if are given the word `art` we can have the following permutions
5454 [ 'tar' ] ]
5555----
5656
57+ Now, let's implement the program to generate all permutations of a word.
5758
58- We already solved this problem using an <<Getting all permutations of a word, iterative program>>, now let's do it using backtracking.
5959
60+ NOTE: We already solved this problem using an <<Getting all permutations of a word, iterative program>>, now let's do it using backtracking.
61+
62+ .Word permutations using backtracking
63+ [source, javascript]
64+ ----
65+ include::{codedir}/algorithms/permutations-backtracking.js[tag=snippet,indent=0]
66+ ----
67+ <1> Iterate through all the elements in the input
68+ <2> Make a change: swap letters
69+ <3> Recursive function moving to the next element
70+ <4> Test if the current change is a solution: reached the end of the string.
71+ <5> Revert back the change (backtracking): Undo swap from step 2
72+
73+ As you can see, we iterate through each letter and swap with the following letters until we reach the end of the string. Then, we rollback the change and try another path.
74+
75+ In the following tree, you can visualize how the backtracking algorithm is swaping the letters.
6076
6177[graphviz, Recursive Fibonacci call tree with dp, svg]
6278....
6379digraph g {
6480 node [shape = record,height=.1];
6581
66- art[label = "<f0> A|<f1> R|<f2> T"];
67- art1[label = "<f0> A|<f1> R|<f2> T"];
82+ art[label = "<f0> A* |<f1> R|<f2> T"];
83+ art1[label = "<f0> A|<f1> R* |<f2> T"];
6884 art2[label = "<f0> A|<f1> R|<f2> T", color="red"];
6985 atr[label = "<f0> A|<f1> T|<f2> R", color="red"];
70- rat[label = "<f0> R|<f1> A|<f2> T"];
86+ rat[label = "<f0> R|<f1> A* |<f2> T"];
7187 rat1[label = "<f0> R|<f1> A|<f2> T", color="red"];
7288 rta[label = "<f0> R|<f1> T|<f2> A", color="red"];
73- tra[label = "<f0> T|<f1> R|<f2> A"];
89+ tra[label = "<f0> T|<f1> R* |<f2> A"];
7490 tra1[label = "<f0> T|<f1> R|<f2> A", color="red"];
7591 tar[label = "<f0> T|<f1> A|<f2> R", color="red"];
7692
@@ -97,18 +113,13 @@ digraph g {
97113}
98114....
99115
116+ .Legend:
117+ - The [red]#red# words are the iterations added to the solution array.
118+ - *Black* arrows indicate the `swap` operations.
119+ - *Grey* arrows indicate the _backtracking_ operation (undo swap).
120+ - The asterisk (`*`) indicates `start` index.
100121
101-
102-
103-
104-
105-
106-
107-
108-
109-
110-
111-
122+ Most of backtracking algorihtms do something similar. What changes is the test function to determine if a current iteration is a solution or not.
112123
113124
114125
0 commit comments