{"id":611,"date":"2023-11-27T06:29:28","date_gmt":"2023-11-27T06:29:28","guid":{"rendered":"https:\/\/favtutor.com\/articles\/?p=611"},"modified":"2023-11-28T09:36:01","modified_gmt":"2023-11-28T09:36:01","slug":"word-search-2-problem","status":"publish","type":"post","link":"https:\/\/favtutor.com\/articles\/word-search-2-problem\/","title":{"rendered":"Word Search II Problem (C++, Java, Python)"},"content":{"rendered":"\n<p>In the world of computer programming, word search puzzles have always been a popular and challenging game to solve. The task of finding words in a grid of letters has fascinated both enthusiasts and developers alike. In this article, we will explore the concept of word search, and discuss an approach to solve the &#8216;word search II&#8217; leetcode problem.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>What is the Word Search II Problem?<\/strong><\/h2>\n\n\n\n<p><strong>The goal of the classic problem word search II is to locate a list of given words that are hidden within a grid of letters. <\/strong>The words can be spelled forward or backward and arranged horizontally, vertically, or diagonally. Each letter in the grid can only be used once to form a word, the main task is to identify words from a jumble of letters and mark them as found.<\/p>\n\n\n\n<p>Let us take an example to understand clearly:<\/p>\n\n\n\n<p class=\"has-black-color has-text-color has-background\" style=\"background-color:#fedcba\"><strong>Input: &nbsp; <\/strong><br>words = [&#8220;fav&#8221;, &#8220;tutor&#8221;, &#8220;pear&#8221;]<br>board = [<br>    [&#8216;t&#8217;, &#8216;u&#8217;, &#8216;a&#8217;, &#8216;p&#8217;],<br>    [&#8216;f&#8217;, &#8216;t&#8217;, &#8216;o&#8217;, &#8216;r&#8217;&nbsp; ],<br>    [&#8216;a&#8217;, &#8216;v&#8217;, &#8216;p&#8217;, &#8216;r&#8217;],<br>    [&#8216;l&#8217;, &#8216;l&#8217;, &#8216;e&#8217;, &#8216;v&#8217;&nbsp; ] ]<br><br><strong>Output:<\/strong> <br>[&#8220;fav&#8221;, &#8220;tutor&#8221;]<\/p>\n\n\n\n<p>In this example, we have a 2D board and a list of words. The task is to find all the words from the list that can be constructed using the letters on the board. In this case, the words &#8220;fav&#8221; and &#8220;tutor&#8221; can be found on the board.<br><\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" width=\"1024\" height=\"533\" src=\"https:\/\/favtutor.com\/articles\/wp-content\/uploads\/2023\/11\/1-1-2-1024x533.png\" alt=\"example of word search ii\n\" class=\"wp-image-617\" srcset=\"https:\/\/favtutor.com\/articles\/wp-content\/uploads\/2023\/11\/1-1-2-1024x533.png 1024w, https:\/\/favtutor.com\/articles\/wp-content\/uploads\/2023\/11\/1-1-2-300x156.png 300w, https:\/\/favtutor.com\/articles\/wp-content\/uploads\/2023\/11\/1-1-2-768x400.png 768w, https:\/\/favtutor.com\/articles\/wp-content\/uploads\/2023\/11\/1-1-2-750x390.png 750w, https:\/\/favtutor.com\/articles\/wp-content\/uploads\/2023\/11\/1-1-2-1140x593.png 1140w, https:\/\/favtutor.com\/articles\/wp-content\/uploads\/2023\/11\/1-1-2.png 1280w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\"><strong>Backtracking Approach: Using Trie<\/strong><\/h2>\n\n\n\n<p>Solving the Word Search II problem using <a href=\"https:\/\/favtutor.com\/blogs\/backtracking-algorithm-problems-cpp\" data-type=\"link\" data-id=\"https:\/\/favtutor.com\/blogs\/backtracking-algorithm-problems-cpp\">backtracking<\/a> efficiently involves using the Trie data structure to store the list of words. <strong>The Trie data structure allows us to build a hierarchical representation of the list words. Each node in the Trie represents a letter, and the paths from the root to the nodes form words.<\/strong><\/p>\n\n\n\n<p>We will follow the given steps to solve this problem:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Create a Trie data structure and insert all the words from the list into the Trie.<\/li>\n<\/ul>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" width=\"1024\" height=\"800\" src=\"https:\/\/favtutor.com\/articles\/wp-content\/uploads\/2023\/11\/2-6-1024x800.png\" alt=\"creating a trie\" class=\"wp-image-618\" srcset=\"https:\/\/favtutor.com\/articles\/wp-content\/uploads\/2023\/11\/2-6-1024x800.png 1024w, https:\/\/favtutor.com\/articles\/wp-content\/uploads\/2023\/11\/2-6-300x234.png 300w, https:\/\/favtutor.com\/articles\/wp-content\/uploads\/2023\/11\/2-6-768x600.png 768w, https:\/\/favtutor.com\/articles\/wp-content\/uploads\/2023\/11\/2-6-750x586.png 750w, https:\/\/favtutor.com\/articles\/wp-content\/uploads\/2023\/11\/2-6-1140x891.png 1140w, https:\/\/favtutor.com\/articles\/wp-content\/uploads\/2023\/11\/2-6.png 1280w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n<\/div>\n\n\n<ul class=\"wp-block-list\">\n<li>Iterate over each cell in the 2D board and perform a depth-first search (DFS) starting from that cell.<\/li>\n\n\n\n<li>In the DFS, check if the current letter in the board exists in the Trie. If it does, move to the next letter and continue the DFS recursively.<\/li>\n\n\n\n<li>If we reach a node in the Trie that represents the end of a word, add that word to the result list.<\/li>\n\n\n\n<li>Keep track of visited cells to avoid reusing the same letter in a word.<\/li>\n<\/ul>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" width=\"1024\" height=\"471\" src=\"https:\/\/favtutor.com\/articles\/wp-content\/uploads\/2023\/11\/3-6-1024x471.png\" alt=\"Applying DFS\" class=\"wp-image-619\" srcset=\"https:\/\/favtutor.com\/articles\/wp-content\/uploads\/2023\/11\/3-6-1024x471.png 1024w, https:\/\/favtutor.com\/articles\/wp-content\/uploads\/2023\/11\/3-6-300x138.png 300w, https:\/\/favtutor.com\/articles\/wp-content\/uploads\/2023\/11\/3-6-768x353.png 768w, https:\/\/favtutor.com\/articles\/wp-content\/uploads\/2023\/11\/3-6-750x345.png 750w, https:\/\/favtutor.com\/articles\/wp-content\/uploads\/2023\/11\/3-6-1140x524.png 1140w, https:\/\/favtutor.com\/articles\/wp-content\/uploads\/2023\/11\/3-6.png 1279w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n<\/div>\n\n\n<ul class=\"wp-block-list\">\n<li>Repeat the DFS for each cell on the board.<\/li>\n\n\n\n<li>After completing the DFS for a cell, mark it as unvisited to allow other paths to use it.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>C++ Code<\/strong><\/h3>\n\n\n\n<p>Below is the C++ program to solve Word Search II problem:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-c++src&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;C++&quot;,&quot;modeName&quot;:&quot;cpp&quot;}\">#include &lt;iostream&gt;\n#include &lt;vector&gt;\n#include &lt;unordered_map&gt;\n\nusing namespace std;\n\nclass TrieNode {\npublic:\n    unordered_map&lt;char, TrieNode*&gt; children;\n    bool isEnd;\n\n    TrieNode() : isEnd(false) {}\n};\n\nclass Trie {\npublic:\n    TrieNode* root;\n\n    Trie() : root(new TrieNode()) {}\n\n    void insert(const string&amp; word) {\n        TrieNode* node = root;\n        for (char c : word) {\n            if (!node-&gt;children.count(c)) {\n                node-&gt;children[c] = new TrieNode();\n            }\n            node = node-&gt;children[c];\n        }\n        node-&gt;isEnd = true;\n    }\n};\n\nclass Solution {\npublic:\n    vector&lt;string&gt; findWords(vector&lt;vector&lt;char&gt;&gt;&amp; board, vector&lt;string&gt;&amp; words) {\n        Trie trie;\n        for (const string&amp; word : words) {\n            trie.insert(word);\n        }\n\n        vector&lt;string&gt; result;\n        int m = board.size();\n        int n = board[0].size();\n\n        for (int i = 0; i &lt; m; ++i) {\n            for (int j = 0; j &lt; n; ++j) {\n                dfs(board, trie.root, i, j, &quot;&quot;, result);\n            }\n        }\n\n        return result;\n    }\n\nprivate:\n    void dfs(vector&lt;vector&lt;char&gt;&gt;&amp; board, TrieNode* node, int i, int j, string path, vector&lt;string&gt;&amp; result) {\n        char c = board[i][j];\n        if (!node-&gt;children.count(c)) {\n            return; \/\/ Stop DFS if the current path is not a prefix of any word\n        }\n\n        node = node-&gt;children[c];\n        if (node-&gt;isEnd) {\n            result.push_back(path + c);\n            node-&gt;isEnd = false; \/\/ Remove the word from the Trie to avoid duplicates\n        }\n\n        board[i][j] = '#'; \/\/ Mark the cell as visited\n\n        \/\/ Explore neighbors in all directions\n        static const vector&lt;pair&lt;int, int&gt;&gt; directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\n        for (const auto&amp; dir : directions) {\n            int ni = i + dir.first;\n            int nj = j + dir.second;\n            if (ni &gt;= 0 &amp;&amp; ni &lt; board.size() &amp;&amp; nj &gt;= 0 &amp;&amp; nj &lt; board[0].size() &amp;&amp; board[ni][nj] != '#') {\n                dfs(board, node, ni, nj, path + c, result);\n            }\n        }\n\n        board[i][j] = c; \/\/ Restore the cell to its original state\n    }\n};\n\nint main() {\n    Solution solution;\n    vector&lt;string&gt; words = {&quot;fav&quot;, &quot;tutor&quot;, &quot;pear&quot;};\n    vector&lt;vector&lt;char&gt;&gt; board = {\n        {'t', 'u', 'a', 'p'},\n        {'f', 't', 'o', 'r'},\n        {'a', 'v', 'p', 'r'},\n        {'l', 'l', 'e', 'v'}\n    };\n\n    vector&lt;string&gt; result = solution.findWords(board, words);\n\n    cout &lt;&lt; &quot;Output: [&quot;;\n    for (int i = 0; i &lt; result.size(); ++i) {\n        cout &lt;&lt; &quot;\\&quot;&quot; &lt;&lt; result[i] &lt;&lt; &quot;\\&quot;&quot;;\n        if (i &lt; result.size() - 1) {\n            cout &lt;&lt; &quot;, &quot;;\n        }\n    }\n    cout &lt;&lt; &quot;]&quot; &lt;&lt; endl;\n\n    return 0;\n}<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Python Code<\/strong><\/h3>\n\n\n\n<p>Below is the Python program to solve the Word Search II problem:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;mode&quot;:&quot;python&quot;,&quot;mime&quot;:&quot;text\/x-python&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;Python&quot;,&quot;modeName&quot;:&quot;python&quot;}\">from typing import List\n\nclass TrieNode:\n    def __init__(self):\n        self.children = {}\n        self.isEnd = False\n\nclass Trie:\n    def __init__(self):\n        self.root = TrieNode()\n\n    def insert(self, word):\n        node = self.root\n        for c in word:\n            if c not in node.children:\n                node.children[c] = TrieNode()\n            node = node.children[c]\n        node.isEnd = True\n\nclass Solution:\n    def findWords(self, board: List[List[str]], words: List[str]) -&gt; List[str]:\n        trie = Trie()\n        for word in words:\n            trie.insert(word)\n\n        result = []\n        m, n = len(board), len(board[0])\n\n        def dfs(node, i, j, path):\n            nonlocal board, result\n\n            if i &lt; 0 or i &gt;= m or j &lt; 0 or j &gt;= n or board[i][j] == '#' or board[i][j] not in node.children:\n                return\n\n            char = board[i][j]\n            node = node.children[char]\n\n            if node.isEnd:\n                result.append(path + char)\n                node.isEnd = False  # Remove the word from the Trie to avoid duplicates\n\n            board[i][j] = '#'  # Mark the cell as visited\n\n            directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]\n            for x, y in directions:\n                ni, nj = i + x, j + y\n                dfs(node, ni, nj, path + char)\n\n            board[i][j] = char  # Restore the cell to its original state\n\n        for i in range(m):\n            for j in range(n):\n                dfs(trie.root, i, j, &quot;&quot;)\n\n        return result\n\nif __name__ == &quot;__main__&quot;:\n    solution = Solution()\n    words = [&quot;fav&quot;, &quot;tutor&quot;, &quot;pear&quot;]\n    board = [\n        ['t', 'u', 'a', 'p'],\n        ['f', 't', 'o', 'r'],\n        ['a', 'v', 'p', 'r'],\n        ['l', 'l', 'e', 'v']\n    ]\n\n    result = solution.findWords(board, words)\n\n    print(&quot;Output:&quot;, result)<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Java Code<\/strong><\/h3>\n\n\n\n<p>Below is the Java program to solve it:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;language&quot;:&quot;Java&quot;,&quot;modeName&quot;:&quot;java&quot;}\">import java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nclass TrieNode {\n    Map&lt;Character, TrieNode&gt; children;\n    boolean isEnd;\n\n    TrieNode() {\n        children = new HashMap&lt;&gt;();\n        isEnd = false;\n    }\n}\n\nclass Trie {\n    TrieNode root;\n\n    Trie() {\n        root = new TrieNode();\n    }\n\n    void insert(String word) {\n        TrieNode node = root;\n        for (char c : word.toCharArray()) {\n            if (!node.children.containsKey(c)) {\n                node.children.put(c, new TrieNode());\n            }\n            node = node.children.get(c);\n        }\n        node.isEnd = true;\n    }\n}\n\npublic class WordSearchII {\n    public List&lt;String&gt; findWords(char[][] board, String[] words) {\n        Trie trie = new Trie();\n        for (String word : words) {\n            trie.insert(word);\n        }\n\n        List&lt;String&gt; result = new ArrayList&lt;&gt;();\n        int m = board.length;\n        int n = board[0].length;\n\n        for (int i = 0; i &lt; m; ++i) {\n            for (int j = 0; j &lt; n; ++j) {\n                dfs(board, trie.root, i, j, &quot;&quot;, result);\n            }\n        }\n\n        return result;\n    }\n\n    private void dfs(char[][] board, TrieNode node, int i, int j, String path, List&lt;String&gt; result) {\n        if (i &lt; 0 || i &gt;= board.length || j &lt; 0 || j &gt;= board[0].length || board[i][j] == '#' || !node.children.containsKey(board[i][j])) {\n            return;\n        }\n\n        char c = board[i][j];\n        node = node.children.get(c);\n\n        if (node.isEnd) {\n            result.add(path + c);\n            node.isEnd = false; \/\/ Remove the word from the Trie to avoid duplicates\n        }\n\n        board[i][j] = '#'; \/\/ Mark the cell as visited\n\n        int[][] directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\n        for (int[] dir : directions) {\n            int ni = i + dir[0];\n            int nj = j + dir[1];\n            dfs(board, node, ni, nj, path + c, result);\n        }\n\n        board[i][j] = c; \/\/ Restore the cell to its original state\n    }\n\n    public static void main(String[] args) {\n        WordSearchII wordSearch = new WordSearchII();\n        String[] words = {&quot;fav&quot;, &quot;tutor&quot;, &quot;pear&quot;};\n        char[][] board = {\n                {'t', 'u', 'a', 'p'},\n                {'f', 't', 'o', 'r'},\n                {'a', 'v', 'p', 'r'},\n                {'l', 'l', 'e', 'v'}\n        };\n\n        List&lt;String&gt; result = wordSearch.findWords(board, words);\n\n        System.out.print(&quot;Output: [&quot;);\n        for (int i = 0; i &lt; result.size(); ++i) {\n            System.out.print(&quot;\\&quot;&quot; + result.get(i) + &quot;\\&quot;&quot;);\n            if (i &lt; result.size() - 1) {\n                System.out.print(&quot;, &quot;);\n            }\n        }\n        System.out.println(&quot;]&quot;);\n    }\n}<\/pre><\/div>\n\n\n\n<p><strong>Output:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code has-black-color has-text-color has-background\" style=\"background-color:#fedcba\"><code>Output: &#91;\"tutor\", \"fav\"]<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Complexity Analysis<\/strong><\/h3>\n\n\n\n<p>Let\u2019s look at the time and space complexity of the same.<\/p>\n\n\n\n<p>For each word in the words array, the code inserts it into the Trie. The insertion operation takes O(L) time, where L is the length of the word.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>If there are N words and the average length of words is M, the total time complexity for inserting all words into the Trie is O(N * M).<\/li>\n<\/ul>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The code performs a Depth-First Search (DFS) on the board starting from each cell. In the worst case, it explores all possible paths on the board.<\/li>\n\n\n\n<li>For each cell, the DFS explores four neighboring cells (up, down, left, right).<\/li>\n<\/ul>\n\n\n\n<p><br>Therefore, the DFS can take up to O(4^(m*n)) (m&amp;n are board dimensions) time in the worst case.<\/p>\n\n\n\n<p><strong>Total Time Complexity is O(4^(m*n)).<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The space required for the Trie depends on the number and length of words. In the worst case, where there are N words with an average length of M, the space complexity is O(N * M).<\/li>\n\n\n\n<li>The DFS is performed recursively, and the maximum depth of recursion is the maximum possible path length on the board.<\/li>\n\n\n\n<li>The maximum depth is O(m * n) in the worst case (when exploring all cells on the board)<\/li>\n<\/ul>\n\n\n\n<p><strong>The overall space complexity is dominated by the Trie, so it is O(N * M).<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Conclusion<\/strong><\/h2>\n\n\n\n<p>In this article, we explored the concept of <a href=\"https:\/\/leetcode.com\/problems\/word-search-ii\/\" target=\"_blank\" data-type=\"link\" data-id=\"https:\/\/leetcode.com\/problems\/word-search-ii\/\" rel=\"noreferrer noopener nofollow\">word search II problem from leetcode<\/a> and discussed an optimized approach to solve this problem using a trie data structure. The Trie approach leverages the hierarchical structure of the Trie to perform fast searches and provides an elegant solution to the word search II problem.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Learn how to solve the Word Search 2 leetcode problem using the Backtracking approach in C++, Java, and Python.<\/p>\n","protected":false},"author":12,"featured_media":614,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jnews-multi-image_gallery":[],"jnews_single_post":null,"jnews_primary_category":{"id":"","hide":""},"footnotes":""},"categories":[7],"tags":[47,14,15],"class_list":["post-611","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-data-structures-algorithms","tag-backtracking","tag-dsa","tag-leetcode"],"_links":{"self":[{"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/posts\/611","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/users\/12"}],"replies":[{"embeddable":true,"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/comments?post=611"}],"version-history":[{"count":3,"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/posts\/611\/revisions"}],"predecessor-version":[{"id":659,"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/posts\/611\/revisions\/659"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/media\/614"}],"wp:attachment":[{"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/media?parent=611"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/categories?post=611"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/tags?post=611"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}