Skip to content

Commit

Permalink
Problem : 186, search word in a grid from a dictionary
Browse files Browse the repository at this point in the history
  • Loading branch information
mandliya committed Feb 3, 2018
1 parent 0e8c0ab commit c0ace54
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 1 deletion.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

| Current Status| Stats |
| :------------: | :----------: |
| Total Problems | 186 |
| Total Problems | 187 |

</center>

Expand Down Expand Up @@ -219,6 +219,7 @@ Include contains single header implementation of data structures and some algori
| :------------ | :----------: |
| You are given a digit string (e.g "1234", "567" etc), provide all possible letter combinations we could generate from this digit string, based on the mapping we see on the telphone/mobile dialpad. If you have typed SMS in old style phones, you would know. For e.g. "1" is mapped to "abc", 2 is mapped to "def". You can refer to the <a href="http://techotv.com/wp-content/uploads/2013/03/Lumia-620-dial-pad-screen-1.jpg" target="_blank">image.</a>. <ul><li> Example: "34" will give output: {"dg","dh","di","eg","eh","ei","fg","fh","fi"} </li></ul> Note that order does not matter in result set.|[dialpad_combinations.cpp](backtracking_problems/dialpad_combinations.cpp)|
| Implement wildcard pattern maching with support for '?' & '*'. <ul><li>'?' Matches any single character.</li></ul><ul><li>'*' Matches any sequence of character.</li></ul>. Checkout examples in file for more details.|[wild_card_matching.cpp](backtracking_problems/wild_card_matching.cpp)|
| Given a 2D board and list of words from a dictionary, find all the possible words on board fromt the list. (Check example in the solution)| [word_search.cpp](backtracking_problems/word_search.cpp)|



Expand Down
142 changes: 142 additions & 0 deletions backtracking_problems/word_search.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/*
* Given a 2D board and list of words from a dictionary,
* find all the possible words on board fromt the list.
* Example:
* words = ["oath","pea","eat","rain"]
* board =
* [
* ['o','a','a','n'],
* ['e','t','a','e'],
* ['i','h','k','r'],
* ['i','f','l','v']
* ]
*
* Output: ["eat", "oath"]
*
* Source : LeetCode Problem 212
*
* Approach:
*
* We can use backtracking(dfs) to traverse from each character on board
* to all four direction. In order to do a fast searching, we can use
* a trie from words in dictionary, as soon as we find a word from dictionary
* in trie, we remove it from trie, so we don't have duplicates.
* Also, we can use the board to mark '#' as visited character to
* achieve backtracking.
*/

#include <vector>
#include <iostream>

struct TrieNode {
std::string word;
std::vector<TrieNode*> children;
TrieNode():
word{""}, children{std::vector<TrieNode*>(26, nullptr)}{}
};

TrieNode* build_trie(const std::vector<std::string>& dictionary)
{
TrieNode* root = new TrieNode();
for (auto word: dictionary) {
TrieNode* curr = root;
for (auto c: word) {
int index = c - 'a';
if (curr->children[index] == nullptr) {
curr->children[index] = new TrieNode();
}
curr = curr->children[index];
}
curr->word = word;
}
return root;
}

void backtrack(std::vector<std::vector<char>>& board,
TrieNode* root, int i, int j, std::vector<std::string>& result)
{
char c = board[i][j];
if (c == '#' || root == nullptr) {
return;
}
int index = c - 'a';
TrieNode* curr = root->children[index];
if (curr == nullptr) {
return;
}

if (curr->word != "") {
result.push_back(curr->word);
// Reset to avoid duplicates.
curr->word = "";
}

board[i][j] = '#';
if (i > 0) {
backtrack(board, curr, i - 1, j, result);
}
if (j > 0) {
backtrack(board, curr, i, j - 1, result);
}
if (i < board.size() - 1) {
backtrack(board, curr, i + 1, j, result);
}
if (j < board[0].size() - 1) {
backtrack(board, curr, i, j + 1, result);
}
board[i][j] = c;
}

std::vector<std::string> find_words(std::vector<std::vector<char>>& board,
std::vector<std::string>& dictionary)
{
std::vector<std::string> result;
for (int i = 0; i < board.size(); ++i) {
for (int j = 0; j < board[0].size(); ++j) {
TrieNode* root = build_trie(dictionary);
backtrack(board, root, i, j, result);
}
}
return result;
}

template <typename T>
void print_vector(const std::vector<T>& vec)
{
std::cout << "{ ";
for (auto t : vec) {
std::cout << t << " ";
}
std::cout << " }" << std::endl;
}

void print_board(const std::vector<std::vector<char>>& board)
{
for (auto v: board) {
print_vector(v);
}
}


int main()
{
std::vector<std::vector<char>> board = {
{'o','a','a','n'},
{'e','t','a','e'},
{'i','h','k','r'},
{'i','f','l','v'}
};

std::vector<std::string> dictionary = {
"oath","pea","eat","rain"
};

std::vector<std::string> result = find_words(board, dictionary);
std::cout << "Board:" << std::endl;
print_board(board);
std::cout << "Dictionary:" << std::endl;
print_vector(dictionary);
std::cout << "Result:" << std::endl;
print_vector(result);
return 0;
}

0 comments on commit c0ace54

Please sign in to comment.