{"id":1865,"date":"2024-03-02T10:54:42","date_gmt":"2024-03-02T10:54:42","guid":{"rendered":"https:\/\/favtutor.com\/articles\/?p=1865"},"modified":"2024-03-02T10:55:04","modified_gmt":"2024-03-02T10:55:04","slug":"walls-and-gates-problem","status":"publish","type":"post","link":"https:\/\/favtutor.com\/articles\/walls-and-gates-problem\/","title":{"rendered":"Walls and Gates Problem (C++, Java, Python)"},"content":{"rendered":"\n<p>There are many algorithms to solve questions related to graphs, a data structure that consists of nodes and edges. For example, to find the shortest path from a given node we can use algorithms like\u00a0<a href=\"https:\/\/favtutor.com\/blogs\/dijkstras-algorithm-cpp\">Dijkstra Algorithm<\/a>, <a href=\"https:\/\/favtutor.com\/blogs\/breadth-first-search-python\">Breadth First Search<\/a>, etc. This article will discuss a similar graph question, known as the Wall and Gates problem. For this question, you should have prior knowledge of BFS.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>What is the Walls and Gates problem?<\/strong><\/h2>\n\n\n\n<p>In the Walls and Gates problem, you are given a matrix or 2-D array in which values can either be:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>0, which represents the door,<\/li>\n\n\n\n<li>-1, which represents the wall,<\/li>\n\n\n\n<li>INF, infinity which represents an empty room.<\/li>\n<\/ul>\n\n\n\n<p>You have to fill all the INF values to a number that represents the minimum distance between that room and any door. You can not walk through walls. So in case we cannot reach any door the value remains INF for that cell. Let\u2019s understand this with an example.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/WqtANrPJbYGq0XUE0-o6dHjtoAUwrDRgf2F8wHGhstk2ugnSVHMCHc1qiPhnkpVCEbzMCkHJAQW-1YGZLGQPrpmCUlOloIZ0YDJvvltfeon1ixS1JEvGXLQUkrxeED3UHiE0tHXY3iwVQLZVDCzatXw\" alt=\"Example for Walls and Gates problem explained\"\/><\/figure>\n\n\n\n<p>In the above matrix, the 1st cell i.e. (0,0) value will be replaced with value 4 as the minimum distance of any gate from this cell is 4. As shown here.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/-PfXO7K6_WrrwFfMN42vNrDKU3jFM92lxuctz_9iLkZZyXtgom_H3s6bCpdj5wo0S3GFvJi0jAEKXVD98_8hd0J8-piZrsFuNyxAneZhKBRb-pWxBdRl-Ihag36X2sigpc71DB21O2FbdTHKKaZObas\" alt=\"(0,0) value will be replaced with value 4\"\/><\/figure>\n\n\n\n<p>The matrix will look like this after putting all values.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/ba3p6pcad5On1F8iDlSicOpxqcUvynKC833gDWqhsBVkTzOqt1IFrekBOuaWdRfaUuHxdNdJzfwVMMrZrZzMVvZyqwLwRvOlmRLAwJkG27Uifd5d0jDc1_PhUo00NU6ALWTcWGpDqweJYBUY45x0HgQ\" alt=\"Matrix after updating all the values\"\/><\/figure>\n\n\n\n<p><strong>The naive solution is to go to each cell and check what is the minimum distance of the gate from that cell. If no such path exists return -1.<\/strong> For checking minimum distance we can use DFS or BFS.<\/p>\n\n\n\n<p>Let\u2019s understand this step by step:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Iterate two loops that go to each cell.<\/li>\n\n\n\n<li>If the cell value is INF, go to adjacent cells by incrementing a count value till it reaches a cell whose value is 0. If it encounters -1 do not move further in that direction.<\/li>\n\n\n\n<li>Now replace the value of the cell with the count value.<\/li>\n\n\n\n<li><\/li>\n<\/ol>\n\n\n\n<p>The time complexity of the above code is\u00a0 O((nm)^2). We are first going to each cell in a matrix whose time complexity is O(nm). After that, we found a minimum distance for this cell which again required O(nm). So, the overall time complexity will be O((nm)^2). The space complexity will remain O(1). As no extra space is needed.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Optimized BFS Approach<\/strong><\/h2>\n\n\n\n<p>In the above approach to solving the Walls and Gates problem, we are using O((nm)^2) time complexity because we are first going to each cell, and then from that cell, we are checking the minimum distance. This can be reduced if we do the reverse approach. <\/p>\n\n\n\n<p><strong>We should start from each gate and then go to each adjacent cell if the cell value is INF and update the value from the previous value + 1.<\/strong> This problem is the same as BFS where we used to find the shortest distance from a cell. The only difference is that here we are pushing more than one initial value.<\/p>\n\n\n\n<p>Let\u2019s examine this approach:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/fXmGwlE7z8pLJDSKWeDZvBVulmOTVkyd58q011XOVlgUOuea1-h0gB89w7d91oZ71qLxgdSoNYyz0EYKefP2vgHsguV1B96v2OlHzdYCnSkfLZr5waV4rkqpq21Ite2YXTXr2xt2ikPeobzbQp8Q7pQ\" alt=\"Optimized Approach\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li>First, create a queue that stores a pair of pairs whose first value is the current value, second represents the number of rows, and third represents the number of columns.&nbsp;<\/li>\n\n\n\n<li>Push all the indexes into the queue which are gates with value 0.<\/li>\n\n\n\n<li>Iterate over this queue till it becomes empty.<\/li>\n\n\n\n<li>Create a sz variable that stores the size of the current element.<\/li>\n\n\n\n<li>Run a loop of size &#8216;sz&#8217; and remove the top element from the queue. Take the value of this element as a current value. Now go to every adjacent cell if the current value + 1 is smaller than their initial value. Now push this value (current value + 1 ) and index into the queue.<\/li>\n\n\n\n<li>Update the value of the cell with the current value + 1.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh7-us.googleusercontent.com\/RI6sGS545hUGxjxLDYOcnXsNyaqzZslYcJWeHqWXktS_t93lyQoe-tQwgnZSGVC5Md89-mh7SWZHWXMIV__ZSO9_XOWyy0RouX7wPeqUWvKj7Ke4zoRQPO3VHK_FyIdZiFZ_wcvTEV74mMpNXiXcER8\" alt=\"Resultant Matrix\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Return the matrix once all the loops are done.<\/li>\n<\/ul>\n\n\n\n<p>Let us now move to code it.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>C++ Code<\/strong><\/h3>\n\n\n\n<p>Here is the C++ program to solve the Walls and Gates 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;bits\/stdc++.h&gt;\nusing namespace std;\n\n\/\/ directions in which one can move i.e. up, down, left, and right.\nvector&lt;pair&lt;int,int&gt;&gt;mov = {{1,0}, {-1,0}, {0,1}, {0,-1}};\n\nbool is_valid(int x, int y, int n, int m){\n    return (x&gt;=0 &amp;&amp; y&gt;=0 &amp;&amp; x&lt;n &amp;&amp; y&lt;m);\n}\n\n\nint main(){\n   \n    vector&lt;vector&lt;int&gt;&gt;grid = {{INT_MAX, 0, INT_MAX}, {INT_MAX, INT_MAX, -1}, {0, -1, INT_MAX }};\n    int n = grid.size(), m = grid[0].size(); \n    queue&lt;pair&lt;int,pair&lt;int,int&gt;&gt;&gt;q;\n    \n    \/\/ inserting all the gates into the queue\n    for(int i=0; i&lt;n; i++){\n       for(int j=0; j&lt;m; j++){\n           if(grid[i][j]==0){\n               q.push({0,{i,j}});\n           }\n       }\n    }\n\n    \/\/ BFS\n    while(q.size()){\n        int sz = q.size();\n        while(sz--){\n            \n            auto p = q.front();\n            q.pop();\n            int count  = p.first, x = p.second.first, y = p.second.second;\n            \n            for(auto cc:mov){\n                int x1 = cc.first, y1 = cc.second; \n                int a = x + x1, b = y + y1;\n                \/\/ checking if a,b are valid index or not \n                if(!is_valid(a,b,n,m) || grid[a][b] &lt;= (count+1)) continue;\n                grid[a][b] = count+1;\n                q.push({count+1, {a, b}});\n            }\n        }\n    }\n\n    \/\/ printing all the values of the matrix\n    for(int i=0; i&lt;n; i++){\n        for(int  j=0; j&lt;m; j++){\n            cout&lt;&lt;grid[i][j]&lt;&lt;&quot; &quot;;\n        }\n        cout&lt;&lt;endl;\n    }\n\n    return 0;\n\n}<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Java Code<\/strong><\/h3>\n\n\n\n<p>Here is the Java program for the solution:<\/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.*;\n\npublic class Main {\n    \/\/ directions in which one can move i.e. up, down, left, and right.\n    static int[][] mov = {{1,0}, {-1,0}, {0,1}, {0,-1}};\n\n    static boolean isValid(int x, int y, int n, int m){\n        return (x&gt;=0 &amp;&amp; y&gt;=0 &amp;&amp; x&lt;n &amp;&amp; y&lt;m);\n    }\n\n    public static void main(String[] args) {\n        int[][] grid = {{Integer.MAX_VALUE, 0, Integer.MAX_VALUE},\n                        {Integer.MAX_VALUE, Integer.MAX_VALUE, -1},\n                        {0, -1, Integer.MAX_VALUE}};\n\n        int n = grid.length, m = grid[0].length;\n        Queue&lt;int[]&gt; q = new LinkedList&lt;&gt;();\n\n        \/\/ inserting all the gates into the queue\n        for(int i = 0; i &lt; n; i++){\n            for(int j = 0; j &lt; m; j++){\n                if(grid[i][j] == 0){\n                    q.add(new int[]{0, i, j});\n                }\n            }\n        }\n\n        \/\/ BFS\n        while(!q.isEmpty()){\n            int sz = q.size();\n            while(sz-- &gt; 0){\n                int[] p = q.poll();\n                int count  = p[0], x = p[1], y = p[2];\n\n                for(int[] cc : mov){\n                    int x1 = cc[0], y1 = cc[1];\n                    int a = x + x1, b = y + y1;\n\n                    \/\/ checking if a,b are valid index or not\n                    if(!isValid(a,b,n,m) || grid[a][b] &lt;= (count+1)) continue;\n                    grid[a][b] = count+1;\n                    q.add(new int[]{count+1, a, b});\n                }\n            }\n        }\n\n        \/\/ printing all the values of the matrix\n        for(int i = 0; i &lt; n; i++){\n            for(int j = 0; j &lt; m; j++){\n                System.out.print(grid[i][j] + &quot; &quot;);\n            }\n            System.out.println();\n        }\n    }\n}<\/pre><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Python Code<\/strong><\/h3>\n\n\n\n<p>You can do it in Python also to crack the Walls and Gates:<\/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 collections import deque\nimport sys\n\n# directions in which one can move i.e. up, down, left and right.\nmov = [(1, 0), (-1, 0), (0, 1), (0, -1)]\n\ndef isValid(x, y, n, m):\n    return (0 &lt;= x &lt; n) and (0 &lt;= y &lt; m)\n\nif __name__ == &quot;__main__&quot;:\n    grid = [[sys.maxsize, 0, sys.maxsize],\n            [sys.maxsize, sys.maxsize, -1],\n            [0, -1, sys.maxsize]]\n\n    n, m = len(grid), len(grid[0])\n    q = deque()\n\n    # inserting all the gates into the queue\n    for i in range(n):\n        for j in range(m):\n            if grid[i][j] == 0:\n                q.append((0, i, j))\n\n    # BFS\n    while q:\n        sz = len(q)\n        while sz &gt; 0:\n            p = q.popleft()\n            count, x, y = p\n\n            for cc in mov:\n                x1, y1 = cc\n                a, b = x + x1, y + y1\n\n                # checking if a, b are valid index or not\n                if not isValid(a, b, n, m) or grid[a][b] &lt;= (count + 1):\n                    continue\n                grid[a][b] = count + 1\n                q.append((count + 1, a, b))\n            sz -= 1\n\n    # printing all the values of the matrix\n    for i in range(n):\n        for j in range(m):\n            print(grid[i][j], end=&quot; &quot;)\n        print()<\/pre><\/div>\n\n\n\n<p><strong>Output:<\/strong>&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-code has-black-color has-text-color has-background has-link-color wp-elements-ba0eade03fe91ede9f83d426a0544490\" style=\"background-color:#fedcba\"><code>1  0  1\n1  1  -1\n0  -1  INF\n<\/code><\/pre>\n\n\n\n<p>Time complexity will be reduced to O(nm) for the Walls and Gates problem using BFS. We are doing BFS traversal only whose time complexity is O(N) where N is the number of traversals. Space complexity will be O(nm). As maximum n*m gates can be possible.<\/p>\n\n\n\n<p>Here is a comparison of both the approaches:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th><strong>Approach<\/strong><\/th><th class=\"has-text-align-center\" data-align=\"center\"><strong>Time Complexity<\/strong><\/th><th class=\"has-text-align-center\" data-align=\"center\"><strong>Space Complexity<\/strong><\/th><th><strong>Description<\/strong><\/th><\/tr><\/thead><tbody><tr><td><em>Brute Force<\/em><\/td><td class=\"has-text-align-center\" data-align=\"center\">O( (nm)^2)&nbsp;&nbsp;&nbsp;<\/td><td class=\"has-text-align-center\" data-align=\"center\">O(1)<\/td><td>We are going to each cell and from each cell we are calculating the minimum distance.<\/td><\/tr><tr><td><em>Optimized Approach<\/em><\/td><td class=\"has-text-align-center\" data-align=\"center\">O( nm )<\/td><td class=\"has-text-align-center\" data-align=\"center\">O(nm)<\/td><td>In this approach, we are using BFS, which traverses the matrix only once.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Conclusion<\/strong><\/h2>\n\n\n\n<p>This article shows how can we find the shortest distance optimally through the BFS algorithm to solve the Walls and Gates problem. The BFS algorithm has a lot more applications. One can learn by solving some more questions based on BFS like\u00a0 Minimum Path Sum, Cherry Pickup, etc. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Understand the Walls and Gates Problem and how to solve it using the BFS Approach with implementation in C++, Java, and Python.<\/p>\n","protected":false},"author":14,"featured_media":1867,"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":[14,15],"class_list":["post-1865","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-data-structures-algorithms","tag-dsa","tag-leetcode"],"_links":{"self":[{"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/posts\/1865","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\/14"}],"replies":[{"embeddable":true,"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/comments?post=1865"}],"version-history":[{"count":3,"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/posts\/1865\/revisions"}],"predecessor-version":[{"id":2128,"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/posts\/1865\/revisions\/2128"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/media\/1867"}],"wp:attachment":[{"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/media?parent=1865"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/categories?post=1865"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/favtutor.com\/articles\/wp-json\/wp\/v2\/tags?post=1865"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}