You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: backtracking/README.md
+39-15
Original file line number
Diff line number
Diff line change
@@ -11,36 +11,60 @@ Backtracking algorithms are typically implemented in these steps:
11
11
1. Prune invalid approaches when possible.
12
12
2. Generate a partial solution by iterating through available alternatives.
13
13
3. Check the validity of the selected alternative according to the problem conditions and rules.
14
-
4. Check for solution completion when required.
14
+
4. Check base cases for solution completion when required.
15
15
16
16
After finding a backtracking approach to a problem we can start coding by creating a driver function and a recursive function.
17
17
18
-
The recursive function should receive as input the current state of the progress and uses it to checks for solution completion and to make the next incremental step by recursively calling itself. The recursive function should also have a way to communicate the solution back to the driver. The driver is responsible for making the first call to the recursive function and interpreting the final solution or failure in finding it back to the caller function. To illustrate this lets solve a problem that we will later solve more efficiently as one of the rehearsals in the [Dynamic Programming](../dp/) section.
19
-
20
-
Sum Up to a Number: Given a set of integers and a positive integer n return true if there is a subset of numbers that can sum up to n and false otherwise. For example for {1,2,3,4,5} and n=10 it should return true because 2+3+5=10 and for n 50 it should return false because there is no subset that can be summed up to 50.
18
+
The recursive function should receive current state of the progress as input and uses it to checks the base cases for solution completion and to make the next incremental step by recursively calling itself. The recursive function should also have a way to communicate the solution back to the driver. The driver is responsible for making the first call to the recursive function and interpreting the final solution or failure in finding it back to the caller function. Lets review an example to illustrate this process.
21
19
22
20
```Go
23
21
package main
24
22
25
-
funcSumUpToNumber(numbers []int, nint) bool {
26
-
returnsumpUpToNumberRecursive(numbers, n, 0)
23
+
import"fmt"
24
+
25
+
// Contains returns true if text contains pattern and false otherwise. For example:
The driver function `SumUpToNumber` prepares the first call to the recursive function by sending it all the input it has received and an index number which starts from 0.
51
+
To solve this problem using the backtracking technique:
52
+
53
+
* Recursively iterate through each character of `text` at `textIndex` and compare it with the first character of the `pattern`:
54
+
55
+
* If they match compare every remaining character in text with every remaining character in pattern and if they are all equal then success base case condition is satisfied.
56
+
* If they are not equal then increment the `textIndex` repeat
57
+
58
+
The driver function `Contains` prepares the first call to the recursive function by sending it all the inputs it has received and to index numbers as `textIndex` and `patternIndex` as 0.
59
+
60
+
The recursive function `containsRecursive` then checks for base cases. If `patternIndex` equals the length of `pattern` it means every character of the pattern has been compared to a substring of text and they have all matched so the function returns true. If `textIndex`equals the length of `text` then all characters have been explored and the pattern has not been found so it returns false.
61
+
62
+
Then it checks to see if the character at `textIndex` in `text` matches the character at `patternIndex` in `pattern`:
63
+
64
+
* If they match it will recursively call the same function to check the remaining characters.
65
+
* If they do not match it backtracks to the next character in text by recursively calling the same function with an incremented textIndex.
42
66
43
-
The recursive function `sumpUpToNumberRecursive` then checks to see if we have reached a satisfying problem condition i.e. a final success or failure and returns it. Then it calls itself in two ways by checking to see if the sum can be achieved by including the value at current index or excluding it.
67
+
For example for inputs `abracadabra` and `cad` it will check to see if `a` equals `c`, if it doesn't then it looks at the next character in text which is `b`. Since it does not match it will keep incrementing `textIndex` until it equals 4 at which point it will match `c`. Then it will check to see if text and pattern match at index 5 and 1. If they do then 6 and 2, and if they do since `cad` has three letters and we have found 3 matching elements we can conclude the text contains the pattern.
Copy file name to clipboardExpand all lines: graph/README.md
+1-1
Original file line number
Diff line number
Diff line change
@@ -175,7 +175,7 @@ For any vertex S that is reachable from V, the simple path in the BFS tree from
175
175
176
176
#### Depth First Search - DFS
177
177
178
-
Depth First Search (DFS) is a graph traversal algorithm that explores a graph as far as possible along each branch before backtracking. When implemented iteratively, it uses a [stack](../stack) data structure, is [recursive](../recursion), and is a generalization of pre-order traversal in trees.
178
+
Depth First Search (DFS) is a graph traversal algorithm that explores a graph as far as possible along each branch before [backtracking](../backtracking/). When implemented iteratively, it uses a [stack](../stack) data structure, is [recursive](../recursion), and is a generalization of pre-order traversal in trees.
179
179
180
180
When given a graph G and a vertex S, DFS systematically discovers all nodes in G reachable from S. It is typically implemented using a driver that discovers the edges of the most recently discovered vertex V with unexplored edges. Once all of V's edges have been explored, the search [backtracks](../backtracking/) to explore all edges leaving the vertex from which V was discovered. This process continues until all the edges are discovered.
0 commit comments