diff --git a/README.md b/README.md
index 23aaf3c..991e485 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
| Current Status| Stats |
| :------------: | :----------: |
-| Total Problems | 186 |
+| Total Problems | 187 |
@@ -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 image..
- Example: "34" will give output: {"dg","dh","di","eg","eh","ei","fg","fh","fi"}
Note that order does not matter in result set.|[dialpad_combinations.cpp](backtracking_problems/dialpad_combinations.cpp)|
| Implement wildcard pattern maching with support for '?' & '*'. - '?' Matches any single character.
- '*' Matches any sequence of character.
. 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)|
diff --git a/backtracking_problems/word_search.cpp b/backtracking_problems/word_search.cpp
new file mode 100644
index 0000000..9b51627
--- /dev/null
+++ b/backtracking_problems/word_search.cpp
@@ -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
+#include
+
+struct TrieNode {
+ std::string word;
+ std::vector children;
+ TrieNode():
+ word{""}, children{std::vector(26, nullptr)}{}
+};
+
+TrieNode* build_trie(const std::vector& 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>& board,
+ TrieNode* root, int i, int j, std::vector& 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 find_words(std::vector>& board,
+ std::vector& dictionary)
+{
+ std::vector 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
+void print_vector(const std::vector& vec)
+{
+ std::cout << "{ ";
+ for (auto t : vec) {
+ std::cout << t << " ";
+ }
+ std::cout << " }" << std::endl;
+}
+
+void print_board(const std::vector>& board)
+{
+ for (auto v: board) {
+ print_vector(v);
+ }
+}
+
+
+int main()
+{
+ std::vector> board = {
+ {'o','a','a','n'},
+ {'e','t','a','e'},
+ {'i','h','k','r'},
+ {'i','f','l','v'}
+ };
+
+ std::vector dictionary = {
+ "oath","pea","eat","rain"
+ };
+
+ std::vector 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;
+}