forked from mandliya/algorithms_and_data_structures
-
Notifications
You must be signed in to change notification settings - Fork 0
/
grid_word_search.cpp
140 lines (122 loc) · 3.67 KB
/
grid_word_search.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
* Search a given word in a 2D board containing letters.
* The word can be constructed by sequentially traversing adjacent
* horizontal or vertical cells. In a sequence to form word,
* letter on same position can not be used more than once.
*
* Example:
* Input:
*
* ['H' 'E' 'Y' 'A']
* ['O' 'L' 'A' 'Y']
* ['I' 'L' 'O' 'V']
*
* Word: HELLO
* Output: Yes/true
*
* Word: YELL
* Output: Yes/true
*
* Word: LOVE
* Output: No/false
*
* Assumption: grid or word does not contain '$' char
*
* Approach: We can use Depth First Search with backtracking to solve this.
* We can search the grid to match the first letter of search word
* in the grid, and then apply depth first search on the grid at that position.
* Finding appropriate next characters in the search word at each depth while
* searching sequentially in the four directions.
*
* We need some way to mark a position in grid as already visited. I will use
* '$' to mark the position as visited, and we will reset the letter at the
* position back to original letter at the end of backtracking.
*
*/
#include <iostream>
#include <vector>
#include <iomanip>
bool depth_first_search(std::vector<std::vector<char>>& grid, const std::string& word,
int r, int c, int index)
{
if (index == word.size()) {
return true;
}
int rows = grid.size();
int cols = grid[0].size();
if (r < 0 || r >= rows || c < 0 || c >= cols) {
return false;
}
if (word[index] != grid[r][c]) {
return false;
}
char cur = grid[r][c];
grid[r][c] = '$';
bool result = false;
result = depth_first_search(grid, word, r - 1, c, index + 1) ||
depth_first_search(grid, word, r + 1, c, index + 1) ||
depth_first_search(grid, word, r, c - 1, index + 1) ||
depth_first_search(grid, word, r, c + 1, index + 1);
grid[r][c] = cur;
return result;
}
bool grid_search(std::vector<std::vector<char>>& grid, const std::string& word)
{
int rows = grid.size();
int cols = grid[0].size();
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
if (word[0] == grid[i][j]) {
if (depth_first_search(grid, word, i, j, 0)) {
return true;
}
}
}
}
return false;
}
void print_grid(const std::vector<std::vector<char>>& grid)
{
for (auto vec : grid) {
std::cout << "{ ";
for (auto c : vec) {
std::cout << c << " ";
}
std::cout << "}" << std::endl;
}
}
int main()
{
std::vector<std::vector<char>> grid{
{'H', 'E', 'Y', 'A'},
{'O', 'L', 'A', 'Y'},
{'I', 'L', 'O', 'V'}
};
print_grid(grid);
std::cout << std::boolalpha;
std::cout << "Does word 'HELLO' exist in grid? ";
bool result = grid_search(grid, "HELLO");
std::cout << result << std::endl;
std::cout << "Does word 'HELL' exist in grid? ";
result = grid_search(grid, "HELL");
std::cout << result << std::endl;
std::cout << "Does word 'LOVE' exist in grid? ";
result = grid_search(grid, "LOVE");
std::cout << result << std::endl;
std::vector<std::vector<char>> grid2 {
{'A','B','C','E'},
{'S','F','C','S'},
{'A','D','E','E'}
};
print_grid(grid2);
std::cout << "Does word 'SEE' exist in grid? ";
result = grid_search(grid2, "SEE");
std::cout << result << std::endl;
std::cout << "Does word 'ABCCSE' exist in grid? ";
result = grid_search(grid2, "ABCCSE");
std::cout << result << std::endl;
std::cout << "Does word 'ABDE' exist in grid? ";
result = grid_search(grid2, "ABDE");
std::cout << result << std::endl;
return 0;
}