<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>grid &#8211; Huahua&#8217;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/tag/grid/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog</link>
	<description></description>
	<lastBuildDate>Fri, 11 Apr 2025 03:36:04 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.7.2</generator>

<image>
	<url>https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/cropped-photo-32x32.jpg</url>
	<title>grid &#8211; Huahua&#8217;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>花花酱 LeetCode 1992. Find All Groups of Farmland</title>
		<link>https://zxi.mytechroad.com/blog/simulation/leetcode-1992-find-all-groups-of-farmland/</link>
					<comments>https://zxi.mytechroad.com/blog/simulation/leetcode-1992-find-all-groups-of-farmland/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Fri, 11 Apr 2025 03:34:14 +0000</pubDate>
				<category><![CDATA[Simulation]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[simulation]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=10315</guid>

					<description><![CDATA[已经告诉你所有的农田都是规整的矩形，题目难度一下子降低了。对于每一个农田的左上角，找到它的宽度和高度即可。然后把整个农田矩形标记为林地/非农田即可。 时间复杂度：O(m*n) 每个格子最多遍历3遍。空间复杂度：O(1) [crayon-67fac1b2ba35b804056087/]]]></description>
										<content:encoded><![CDATA[
<p>已经告诉你所有的农田都是规整的矩形，题目难度一下子降低了。<br>对于每一个农田的左上角，找到它的宽度和高度即可。<br>然后把整个农田矩形标记为林地/非农田即可。</p>



<p>时间复杂度：O(m*n) 每个格子最多遍历3遍。<br>空间复杂度：O(1)</p>



<pre class="urvanov-syntax-highlighter-plain-tag">class Solution {
public:
  vector&lt;vector&lt;int&gt;&gt; findFarmland(vector&lt;vector&lt;int&gt;&gt;&amp; land) {
    const int m = land.size();
    const int n = land[0].size();
    vector&lt;vector&lt;int&gt;&gt; ans;
    for (int i = 0; i &lt; m; ++i)
      for (int j = 0; j &lt; n; ++j) {
        if (!land[i][j]) continue;
        int w = 0;
        int h = 0;
        while (j + w &lt; n &amp;&amp; land[i][j + w]) ++w;
        while (i + h &lt; m &amp;&amp; land[i + h][j]) ++h;
        ans.push_back({i, j, i + h - 1, j + w - 1});
        for (int p = 0; p &lt; h; ++p)
          for (int q = 0; q &lt; w; ++q)
            land[i + p][j + q] = 0; // mark as seen.
      }
    return ans;
  }
};</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/simulation/leetcode-1992-find-all-groups-of-farmland/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2435. Paths in Matrix Whose Sum Is Divisible by K</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-2435-paths-in-matrix-whose-sum-is-divisible-by-k/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-2435-paths-in-matrix-whose-sum-is-divisible-by-k/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Tue, 11 Oct 2022 01:04:27 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[paths]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9854</guid>

					<description><![CDATA[You are given a&#160;0-indexed&#160;m x n&#160;integer matrix&#160;grid&#160;and an integer&#160;k. You are currently at position&#160;(0, 0)&#160;and you want to reach position&#160;(m - 1, n - 1)&#160;moving&#8230;]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="花花酱 LeetCode 2435. Paths in Matrix Whose Sum Is Divisible by K - 刷题找工作 EP403" width="500" height="281" src="https://www.youtube.com/embed/Gj8mvPsRkBI?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<p>You are given a&nbsp;<strong>0-indexed</strong>&nbsp;<code>m x n</code>&nbsp;integer matrix&nbsp;<code>grid</code>&nbsp;and an integer&nbsp;<code>k</code>. You are currently at position&nbsp;<code>(0, 0)</code>&nbsp;and you want to reach position&nbsp;<code>(m - 1, n - 1)</code>&nbsp;moving only&nbsp;<strong>down</strong>&nbsp;or&nbsp;<strong>right</strong>.</p>



<p>Return<em>&nbsp;the number of paths where the sum of the elements on the path is divisible by&nbsp;</em><code>k</code>. Since the answer may be very large, return it&nbsp;<strong>modulo</strong>&nbsp;<code>10<sup>9</sup>&nbsp;+ 7</code>.</p>



<p><strong>Example 1:</strong></p>



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2022/08/13/image-20220813183124-1.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> grid = [[5,2,4],[3,0,5],[0,7,2]], k = 3
<strong>Output:</strong> 2
<strong>Explanation:</strong> There are two paths where the sum of the elements on the path is divisible by k.
The first path highlighted in red has a sum of 5 + 2 + 4 + 5 + 2 = 18 which is divisible by 3.
The second path highlighted in blue has a sum of 5 + 3 + 0 + 5 + 2 = 15 which is divisible by 3.
</pre>



<p><strong>Example 2:</strong></p>



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2022/08/17/image-20220817112930-3.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> grid = [[0,0]], k = 5
<strong>Output:</strong> 1
<strong>Explanation:</strong> The path highlighted in red has a sum of 0 + 0 = 0 which is divisible by 5.
</pre>



<p><strong>Example 3:</strong></p>



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2022/08/12/image-20220812224605-3.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> grid = [[7,3,4,9],[2,3,6,2],[2,3,7,0]], k = 1
<strong>Output:</strong> 10
<strong>Explanation:</strong> Every integer is divisible by 1 so the sum of the elements on every possible path is divisible by k.
</pre>



<p><strong>Constraints:</strong></p>



<ul class="wp-block-list"><li><code>m == grid.length</code></li><li><code>n == grid[i].length</code></li><li><code>1 &lt;= m, n &lt;= 5 * 10<sup>4</sup></code></li><li><code>1 &lt;= m * n &lt;= 5 * 10<sup>4</sup></code></li><li><code>0 &lt;= grid[i][j] &lt;= 100</code></li><li><code>1 &lt;= k &lt;= 50</code></li></ul>



<h2 class="wp-block-heading"><strong>Solution: DP</strong></h2>



<figure class="wp-block-image size-full"><a href="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/10/2435-ep403-1.png"><img fetchpriority="high" decoding="async" width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/10/2435-ep403-1.png" alt="" class="wp-image-9858" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/10/2435-ep403-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2022/10/2435-ep403-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2022/10/2435-ep403-1-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></figure>



<figure class="wp-block-image size-full"><a href="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/10/2435-ep403-2.png"><img decoding="async" width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/10/2435-ep403-2.png" alt="" class="wp-image-9859" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/10/2435-ep403-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2022/10/2435-ep403-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2022/10/2435-ep403-2-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></figure>



<figure class="wp-block-image size-full"><a href="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/10/2435-ep403-3.png"><img loading="lazy" decoding="async" width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/10/2435-ep403-3.png" alt="" class="wp-image-9861" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2022/10/2435-ep403-3.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2022/10/2435-ep403-3-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2022/10/2435-ep403-3-768x432.png 768w" sizes="auto, (max-width: 960px) 100vw, 960px" /></a></figure>



<p>Let dp[i][j][r] := # of paths from (0,0) to (i,j) with path sum % k == r.<br><br>init: dp[0][0][grid[0][0] % k] = 1</p>



<p>dp[i][j][(r + grid[i][j]) % k] = dp[i-1][j][r] + dp[i][j-1][r]</p>



<p>ans = dp[m-1][n-1][0]</p>



<p>Time complexity: O(m*n*k)<br>Space complexity: O(m*n*k) -&gt; O(n*k)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  int numberOfPaths(vector&lt;vector&lt;int&gt;&gt;&amp; grid, int k) {
    const int kMod = 1e9 + 7;
    const int m = grid.size();
    const int n = grid[0].size();
    vector&lt;vector&lt;vector&lt;int&gt;&gt;&gt; dp(m, vector&lt;vector&lt;int&gt;&gt;(n, vector&lt;int&gt;(k)));
    dp[0][0][grid[0][0] % k] = 1;
    for (int i = 0; i &lt; m; ++i)
      for (int j = 0; j &lt; n; ++j) {
        if (i == 0 &amp;&amp; j == 0) continue;
        for (int r = 0; r &lt; k; ++r)
          dp[i][j][(r + grid[i][j]) % k] = 
            ((j ? dp[i][j - 1][r] : 0) + (i ? dp[i - 1][j][r] : 0)) % kMod;          
      }
    return dp[m - 1][n - 1][0];
  }
};</pre>
</div></div>



<p>Related Problems:</p>



<ul class="wp-block-list"><li><a href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-62-unique-paths/" data-type="post" data-id="187">花花酱 LeetCode 62. Unique Paths</a></li></ul>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-2435-paths-in-matrix-whose-sum-is-divisible-by-k/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2257. Count Unguarded Cells in the Grid</title>
		<link>https://zxi.mytechroad.com/blog/simulation/leetcode-2257-count-unguarded-cells-in-the-grid/</link>
					<comments>https://zxi.mytechroad.com/blog/simulation/leetcode-2257-count-unguarded-cells-in-the-grid/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 02 May 2022 05:37:13 +0000</pubDate>
				<category><![CDATA[Simulation]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[simulation]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9710</guid>

					<description><![CDATA[You are given two integers&#160;m&#160;and&#160;n&#160;representing a&#160;0-indexed&#160;m x n&#160;grid. You are also given two 2D integer arrays&#160;guards&#160;and&#160;walls&#160;where&#160;guards[i] = [rowi, coli]&#160;and&#160;walls[j] = [rowj, colj]&#160;represent the positions of&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You are given two integers&nbsp;<code>m</code>&nbsp;and&nbsp;<code>n</code>&nbsp;representing a&nbsp;<strong>0-indexed</strong>&nbsp;<code>m x n</code>&nbsp;grid. You are also given two 2D integer arrays&nbsp;<code>guards</code>&nbsp;and&nbsp;<code>walls</code>&nbsp;where&nbsp;<code>guards[i] = [row<sub>i</sub>, col<sub>i</sub>]</code>&nbsp;and&nbsp;<code>walls[j] = [row<sub>j</sub>, col<sub>j</sub>]</code>&nbsp;represent the positions of the&nbsp;<code>i<sup>th</sup></code>&nbsp;guard and&nbsp;<code>j<sup>th</sup></code>&nbsp;wall respectively.</p>



<p>A guard can see&nbsp;<strong>every</strong>&nbsp;cell in the four cardinal directions (north, east, south, or west) starting from their position unless&nbsp;<strong>obstructed</strong>&nbsp;by a wall or another guard. A cell is&nbsp;<strong>guarded</strong>&nbsp;if there is&nbsp;<strong>at least</strong>&nbsp;one guard that can see it.</p>



<p>Return<em>&nbsp;the number of unoccupied cells that are&nbsp;<strong>not</strong>&nbsp;<strong>guarded</strong>.</em></p>



<p><strong>Example 1:</strong></p>



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2022/03/10/example1drawio2.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> m = 4, n = 6, guards = [[0,0],[1,1],[2,3]], walls = [[0,1],[2,2],[1,4]]
<strong>Output:</strong> 7
<strong>Explanation:</strong> The guarded and unguarded cells are shown in red and green respectively in the above diagram.
There are a total of 7 unguarded cells, so we return 7.
</pre>



<p><strong>Example 2:</strong></p>



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2022/03/10/example2drawio.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> m = 3, n = 3, guards = [[1,1]], walls = [[0,1],[1,0],[2,1],[1,2]]
<strong>Output:</strong> 4
<strong>Explanation:</strong> The unguarded cells are shown in green in the above diagram.
There are a total of 4 unguarded cells, so we return 4.
</pre>



<p><strong>Constraints:</strong></p>



<ul class="wp-block-list"><li><code>1 &lt;= m, n &lt;= 10<sup>5</sup></code></li><li><code>2 &lt;= m * n &lt;= 10<sup>5</sup></code></li><li><code>1 &lt;= guards.length, walls.length &lt;= 5 * 10<sup>4</sup></code></li><li><code>2 &lt;= guards.length + walls.length &lt;= m * n</code></li><li><code>guards[i].length == walls[j].length == 2</code></li><li><code>0 &lt;= row<sub>i</sub>, row<sub>j</sub>&nbsp;&lt; m</code></li><li><code>0 &lt;= col<sub>i</sub>, col<sub>j</sub>&nbsp;&lt; n</code></li><li>All the positions in&nbsp;<code>guards</code>&nbsp;and&nbsp;<code>walls</code>&nbsp;are&nbsp;<strong>unique</strong>.</li></ul>



<h2 class="wp-block-heading"><strong>Solution: Simulation</strong></h2>



<p>Enumerate each cell, for each guard, shoot rays to 4 directions, mark cells on the way to 1 and stop when hit a guard or a wall. </p>



<p>Time complexity: O(mn)<br>Space complexity: O(mn)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  int countUnguarded(int m, int n, vector&lt;vector&lt;int&gt;&gt;&amp; guards, vector&lt;vector&lt;int&gt;&gt;&amp; walls) {
    vector&lt;vector&lt;int&gt;&gt; s(m, vector&lt;int&gt;(n));
    for (const auto&amp; g : guards)
      s[g[0]][g[1]] = 2;
    
    for (const auto&amp; w : walls)
      s[w[0]][w[1]] = 3;
    
    for (int i = 0; i &lt; m; ++i)
      for (int j = 0; j &lt; n; ++j) {
        if (s[i][j] != 2) continue;
        for (int y = i - 1; y &gt;= 0; s[y--][j] = 1)
          if (s[y][j] &gt;= 2) break;          
        for (int y = i + 1; y &lt; m; s[y++][j] = 1)
          if (s[y][j] &gt;= 2) break;        
        for (int x = j - 1; x &gt;= 0; s[i][x--] = 1)
          if (s[i][x] &gt;= 2) break;    
        for (int x = j + 1; x &lt; n; s[i][x++] = 1)
          if (s[i][x] &gt;= 2) break;          
      }    
    int ans = 0;
    for (int i = 0; i &lt; m; ++i)
      for (int j = 0; j &lt; n; ++j)
        ans += !s[i][j];
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/simulation/leetcode-2257-count-unguarded-cells-in-the-grid/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2146. K Highest Ranked Items Within a Price Range</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-2146-k-highest-ranked-items-within-a-price-range/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-2146-k-highest-ranked-items-within-a-price-range/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Fri, 04 Feb 2022 01:23:04 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[BFS]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[shortest path]]></category>
		<category><![CDATA[sorting]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9458</guid>

					<description><![CDATA[You are given a&#160;0-indexed&#160;2D integer array&#160;grid&#160;of size&#160;m x n&#160;that represents a map of the items in a shop. The integers in the grid represent the&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You are given a&nbsp;<strong>0-indexed</strong>&nbsp;2D integer array&nbsp;<code>grid</code>&nbsp;of size&nbsp;<code>m x n</code>&nbsp;that represents a map of the items in a shop. The integers in the grid represent the following:</p>



<ul class="wp-block-list"><li><code>0</code>&nbsp;represents a wall that you cannot pass through.</li><li><code>1</code>&nbsp;represents an empty cell that you can freely move to and from.</li><li>All other positive integers represent the price of an item in that cell. You may also freely move to and from these item cells.</li></ul>



<p>It takes&nbsp;<code>1</code>&nbsp;step to travel between adjacent grid cells.</p>



<p>You are also given integer arrays&nbsp;<code>pricing</code>&nbsp;and&nbsp;<code>start</code>&nbsp;where&nbsp;<code>pricing = [low, high]</code>&nbsp;and&nbsp;<code>start = [row, col]</code>&nbsp;indicates that you start at the position&nbsp;<code>(row, col)</code>&nbsp;and are interested only in items with a price in the range of&nbsp;<code>[low, high]</code>&nbsp;(<strong>inclusive</strong>). You are further given an integer&nbsp;<code>k</code>.</p>



<p>You are interested in the&nbsp;<strong>positions</strong>&nbsp;of the&nbsp;<code>k</code>&nbsp;<strong>highest-ranked</strong>&nbsp;items whose prices are&nbsp;<strong>within</strong>&nbsp;the given price range. The rank is determined by the&nbsp;<strong>first</strong>&nbsp;of these criteria that is different:</p>



<ol class="wp-block-list"><li>Distance, defined as the length of the shortest path from the&nbsp;<code>start</code>&nbsp;(<strong>shorter</strong>&nbsp;distance has a higher rank).</li><li>Price (<strong>lower</strong>&nbsp;price has a higher rank, but it must be&nbsp;<strong>in the price range</strong>).</li><li>The row number (<strong>smaller</strong>&nbsp;row number has a higher rank).</li><li>The column number (<strong>smaller</strong>&nbsp;column number has a higher rank).</li></ol>



<p>Return&nbsp;<em>the&nbsp;</em><code>k</code><em>&nbsp;highest-ranked items within the price range&nbsp;<strong>sorted</strong>&nbsp;by their rank (highest to lowest)</em>. If there are fewer than&nbsp;<code>k</code>&nbsp;reachable items within the price range, return&nbsp;<em><strong>all</strong>&nbsp;of them</em>.</p>



<p><strong>Example 1:</strong></p>



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2021/12/16/example1drawio.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> grid = [[1,2,0,1],[1,3,0,1],[0,2,5,1]], pricing = [2,5], start = [0,0], k = 3
<strong>Output:</strong> [[0,1],[1,1],[2,1]]
<strong>Explanation:</strong> You start at (0,0).
With a price range of [2,5], we can take items from (0,1), (1,1), (2,1) and (2,2).
The ranks of these items are:
- (0,1) with distance 1
- (1,1) with distance 2
- (2,1) with distance 3
- (2,2) with distance 4
Thus, the 3 highest ranked items in the price range are (0,1), (1,1), and (2,1).
</pre>



<p><strong>Example 2:</strong></p>



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2021/12/16/example2drawio1.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> grid = [[1,2,0,1],[1,3,3,1],[0,2,5,1]], pricing = [2,3], start = [2,3], k = 2
<strong>Output:</strong> [[2,1],[1,2]]
<strong>Explanation:</strong> You start at (2,3).
With a price range of [2,3], we can take items from (0,1), (1,1), (1,2) and (2,1).
The ranks of these items are:
- (2,1) with distance 2, price 2
- (1,2) with distance 2, price 3
- (1,1) with distance 3
- (0,1) with distance 4
Thus, the 2 highest ranked items in the price range are (2,1) and (1,2).
</pre>



<p><strong>Example 3:</strong></p>



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2021/12/30/example3.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> grid = [[1,1,1],[0,0,1],[2,3,4]], pricing = [2,3], start = [0,0], k = 3
<strong>Output:</strong> [[2,1],[2,0]]
<strong>Explanation:</strong> You start at (0,0).
With a price range of [2,3], we can take items from (2,0) and (2,1). 
The ranks of these items are: 
- (2,1) with distance 5
- (2,0) with distance 6
Thus, the 2 highest ranked items in the price range are (2,1) and (2,0). 
Note that k = 3 but there are only 2 reachable items within the price range.
</pre>



<p><strong>Constraints:</strong></p>



<ul class="wp-block-list"><li><code>m == grid.length</code></li><li><code>n == grid[i].length</code></li><li><code>1 &lt;= m, n &lt;= 10<sup>5</sup></code></li><li><code>1 &lt;= m * n &lt;= 10<sup>5</sup></code></li><li><code>0 &lt;= grid[i][j] &lt;= 10<sup>5</sup></code></li><li><code>pricing.length == 2</code></li><li><code>2 &lt;= low &lt;= high &lt;= 10<sup>5</sup></code></li><li><code>start.length == 2</code></li><li><code>0 &lt;= row &lt;= m - 1</code></li><li><code>0 &lt;= col &lt;= n - 1</code></li><li><code>grid[row][col] &gt; 0</code></li><li><code>1 &lt;= k &lt;= m * n</code></li></ul>



<h2 class="wp-block-heading"><strong>Solution: BFS + Sorting</strong></h2>



<p>Use BFS to collect reachable cells and sort afterwards.</p>



<p>Time complexity: O(mn + KlogK) where K = # of reachable cells.</p>



<p>Space complexity: O(mn)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  vector&lt;vector&lt;int&gt;&gt; highestRankedKItems(vector&lt;vector&lt;int&gt;&gt;&amp; grid, vector&lt;int&gt;&amp; pricing, vector&lt;int&gt;&amp; start, int k) {
    const int m = grid.size();
    const int n = grid[0].size();    
    const vector&lt;int&gt; dirs{1, 0, -1, 0, 1};    
    vector&lt;vector&lt;int&gt;&gt; seen(m, vector&lt;int&gt;(n));
    seen[start[0]][start[1]] = 1;
    vector&lt;vector&lt;int&gt;&gt; cells;
    queue&lt;array&lt;int, 3&gt;&gt; q;
    q.push({start[0], start[1], 0});
    while (!q.empty()) {
      auto [y, x, d] = q.front(); q.pop();
      if (grid[y][x] &gt;= pricing[0] &amp;&amp; grid[y][x] &lt;= pricing[1])
          cells.push_back({d, grid[y][x], y, x});
      for (int i = 0; i &lt; 4; ++i) {
        const int tx = x + dirs[i];
        const int ty = y + dirs[i + 1];
        if (tx &lt; 0 || tx &gt;= n || ty &lt; 0 || ty &gt;= m 
            || !grid[ty][tx] || seen[ty][tx]++) continue;
        q.push({ty, tx, d + 1});
      }
    }
    sort(begin(cells), end(cells), less&lt;vector&lt;int&gt;&gt;());
    vector&lt;vector&lt;int&gt;&gt; ans;
    for (int i = 0; i &lt; min(k, (int)(cells.size())); ++i)
      ans.push_back({cells[i][2], cells[i][3]});
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-2146-k-highest-ranked-items-within-a-price-range/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1391. Check if There is a Valid Path in a Grid</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-1391-check-if-there-is-a-valid-path-in-a-grid/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-1391-check-if-there-is-a-valid-path-in-a-grid/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 22 Mar 2020 10:46:31 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[BFS]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[O(mn)]]></category>
		<category><![CDATA[search]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=6526</guid>

					<description><![CDATA[Given a&#160;m&#160;x&#160;ngrid. Each cell of the&#160;grid&#160;represents a street. The street of&#160;grid[i][j]&#160;can be: 1&#160;which means a street connecting the left cell and the right cell. 2&#160;which&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Given a&nbsp;<em>m</em>&nbsp;x&nbsp;<em>n</em><code>grid</code>. Each cell of the&nbsp;<code>grid</code>&nbsp;represents a street. The street of&nbsp;<code>grid[i][j]</code>&nbsp;can be:</p>



<ul class="wp-block-list"><li><strong>1</strong>&nbsp;which means a street connecting the left cell and the right cell.</li><li><strong>2</strong>&nbsp;which means a street connecting the upper cell and the lower cell.</li><li><strong>3</strong>&nbsp;which means a street connecting the left cell and the lower cell.</li><li><strong>4</strong>&nbsp;which means a street connecting the right cell and the lower cell.</li><li><strong>5</strong>&nbsp;which means a street connecting the left cell and the upper cell.</li><li><strong>6</strong>&nbsp;which means a street connecting the right cell and the upper cell.</li></ul>



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2020/03/05/main.png" alt=""/></figure>



<p>You will initially start at the street of the&nbsp;upper-left cell&nbsp;<code>(0,0)</code>. A valid path in the grid is a path which starts from the upper left&nbsp;cell&nbsp;<code>(0,0)</code>&nbsp;and ends at the bottom-right&nbsp;cell&nbsp;<code>(m - 1, n - 1)</code>.&nbsp;<strong>The path should only follow the streets</strong>.</p>



<p><strong>Notice</strong>&nbsp;that you are&nbsp;<strong>not allowed</strong>&nbsp;to change any street.</p>



<p>Return&nbsp;<em>true</em>&nbsp;if there is a valid path in the grid or&nbsp;<em>false</em>&nbsp;otherwise.</p>



<p><strong>Example 1:</strong></p>



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2020/03/05/e1.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> grid = [[2,4,3],[6,5,2]]
<strong>Output:</strong> true
<strong>Explanation:</strong> As shown you can start at cell (0, 0) and visit all the cells of the grid to reach (m - 1, n - 1).
</pre>



<p><strong>Example 2:</strong></p>



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2020/03/05/e2.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> grid = [[1,2,1],[1,2,1]]
<strong>Output:</strong> false
<strong>Explanation:</strong> As shown you the street at cell (0, 0) is not connected with any street of any other cell and you will get stuck at cell (0, 0)
</pre>



<p><strong>Example 3:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> grid = [[1,1,2]]
<strong>Output:</strong> false
<strong>Explanation:</strong> You will get stuck at cell (0, 1) and you cannot reach cell (0, 2).
</pre>



<p><strong>Example 4:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> grid = [[1,1,1,1,1,1,3]]
<strong>Output:</strong> true
</pre>



<p><strong>Example 5:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> grid = [[2],[2],[2],[2],[2],[2],[6]]
<strong>Output:</strong> true
</pre>



<p><strong>Constraints:</strong></p>



<ul class="wp-block-list"><li><code>m == grid.length</code></li><li><code>n == grid[i].length</code></li><li><code>1 &lt;= m, n &lt;= 300</code></li><li><code>1 &lt;= grid[i][j] &lt;= 6</code></li></ul>



<h2 class="wp-block-heading"><strong>Solution: BFS</strong></h2>



<p>Need to check both sides (x, y) -&gt; (tx, ty) and (tx, ty) -&gt; (x, y) to make sure a path exist.</p>



<p>Time complexity: O(m*n)<br>Space complexity: O(m*n)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  bool hasValidPath(vector&lt;vector&lt;int&gt;&gt;&amp; grid) {
    const int m = grid.size();
    const int n = grid[0].size();
    vector&lt;int&gt; dirs{0, -1, 0, 1, 0}; // [up, left, down, right]    
    vector&lt;set&lt;int&gt;&gt; rules{
      {1, 3}, {0, 2}, {1, 2}, 
      {2, 3}, {0, 1}, {0, 3}};
    queue&lt;int&gt; q{{0}};
    vector&lt;int&gt; seen(m * n);
    seen[0] = 1;
    while (!q.empty()) {
      int cx = q.front() % n;
      int cy = q.front() / n;      
      q.pop();
      if (cx == n - 1 &amp;&amp; cy == m - 1) return true;      
      for (int d : rules[grid[cy][cx] - 1]) {
        int x = cx + dirs[d];
        int y = cy + dirs[d + 1];
        int key = y * n + x;
        if (x &lt; 0 || x &gt;= n || y &lt; 0 || y &gt;= m || seen[key] 
           || !rules[grid[y][x] - 1].count((d + 2) % 4)) continue;
        seen[key] = 1;
        q.push(key);
      }
    }
    return false;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-1391-check-if-there-is-a-valid-path-in-a-grid/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 529. Minesweeper</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-529-minesweeper/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-529-minesweeper/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Tue, 10 Mar 2020 03:18:39 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[medium]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=6447</guid>

					<description><![CDATA[Let&#8217;s play the minesweeper game (Wikipedia,&#160;online game)! You are given a 2D char matrix representing the game board.&#160;&#8216;M&#8217;&#160;represents an&#160;unrevealed&#160;mine,&#160;&#8216;E&#8217;&#160;represents an&#160;unrevealed&#160;empty square,&#160;&#8216;B&#8217;&#160;represents a&#160;revealed&#160;blank square that has&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Let&#8217;s play the minesweeper game (<a href="https://en.wikipedia.org/wiki/Minesweeper_(video_game)">Wikipedia</a>,&nbsp;<a href="http://minesweeperonline.com/">online game</a>)!</p>



<p>You are given a 2D char matrix representing the game board.&nbsp;<strong>&#8216;M&#8217;</strong>&nbsp;represents an&nbsp;<strong>unrevealed</strong>&nbsp;mine,&nbsp;<strong>&#8216;E&#8217;</strong>&nbsp;represents an&nbsp;<strong>unrevealed</strong>&nbsp;empty square,&nbsp;<strong>&#8216;B&#8217;</strong>&nbsp;represents a&nbsp;<strong>revealed</strong>&nbsp;blank square that has no adjacent (above, below, left, right, and all 4 diagonals) mines,&nbsp;<strong>digit</strong>&nbsp;(&#8216;1&#8217; to &#8216;8&#8217;) represents how many mines are adjacent to this&nbsp;<strong>revealed</strong>&nbsp;square, and finally&nbsp;<strong>&#8216;X&#8217;</strong>&nbsp;represents a&nbsp;<strong>revealed</strong>&nbsp;mine.</p>



<p>Now given the next click position (row and column indices) among all the&nbsp;<strong>unrevealed</strong>&nbsp;squares (&#8216;M&#8217; or &#8216;E&#8217;), return the board after revealing this position according to the following rules:</p>



<ol class="wp-block-list"><li>If a mine (&#8216;M&#8217;) is revealed, then the game is over &#8211; change it to&nbsp;<strong>&#8216;X&#8217;</strong>.</li><li>If an empty square (&#8216;E&#8217;) with&nbsp;<strong>no adjacent mines</strong>&nbsp;is revealed, then change it to revealed blank (&#8216;B&#8217;) and all of its adjacent&nbsp;<strong>unrevealed</strong>&nbsp;squares should be revealed recursively.</li><li>If an empty square (&#8216;E&#8217;) with&nbsp;<strong>at least one adjacent mine</strong>&nbsp;is revealed, then change it to a digit (&#8216;1&#8217; to &#8216;8&#8217;) representing the number of adjacent mines.</li><li>Return the board when no more squares will be revealed.</li></ol>



<p><strong>Example 1:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> 

[['E', 'E', 'E', 'E', 'E'],
 ['E', 'E', 'M', 'E', 'E'],
 ['E', 'E', 'E', 'E', 'E'],
 ['E', 'E', 'E', 'E', 'E']]

Click : [3,0]

<strong>Output:</strong> 

[['B', '1', 'E', '1', 'B'],
 ['B', '1', 'M', '1', 'B'],
 ['B', '1', '1', '1', 'B'],
 ['B', 'B', 'B', 'B', 'B']]

<strong>Explanation:</strong>

</pre>



<p><strong>Example 2:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> 

[['B', '1', 'E', '1', 'B'],
 ['B', '1', 'M', '1', 'B'],
 ['B', '1', '1', '1', 'B'],
 ['B', 'B', 'B', 'B', 'B']]

Click : [1,2]

<strong>Output:</strong> 

[['B', '1', 'E', '1', 'B'],
 ['B', '1', 'X', '1', 'B'],
 ['B', '1', '1', '1', 'B'],
 ['B', 'B', 'B', 'B', 'B']]

<strong>Explanation:</strong>

</pre>



<p><strong>Note:</strong></p>



<ol class="wp-block-list"><li>The range of the input matrix&#8217;s height and width is [1,50].</li><li>The click position will only be an unrevealed square (&#8216;M&#8217; or &#8216;E&#8217;), which also means the input board contains at least one clickable square.</li><li>The input board won&#8217;t be a stage when game is over (some mines have been revealed).</li><li>For simplicity, not mentioned rules should be ignored in this problem. For example, you&nbsp;<strong>don&#8217;t</strong>&nbsp;need to reveal all the unrevealed mines when the game is over, consider any cases that you will win the game or flag any squares.</li></ol>



<h2 class="wp-block-heading"><strong>Solution: DFS</strong></h2>



<p>Time complexity: O(m*n)<br>Space complexity: O(m* n)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  vector&lt;vector&lt;char&gt;&gt; updateBoard(vector&lt;vector&lt;char&gt;&gt;&amp; board, vector&lt;int&gt;&amp; click) {
    const int m = board.size();
    const int n = board[0].size();
    function&lt;void(int, int)&gt; dfs = [&amp;](int x, int y) {
      if (board[y][x] != 'E') return;
      int c = 0;
      for (int tx = x - 1; tx &lt;= x + 1; ++tx)
        for (int ty = y - 1; ty &lt;= y + 1; ++ty)
          if (tx &gt;= 0 &amp;&amp; tx &lt; n &amp;&amp; ty &gt;= 0 &amp;&amp; ty &lt; m)
            c += board[ty][tx] == 'M';
      
      if (c &gt; 0) {
        board[y][x] = '0' + c;
        return;      
      }
      
      board[y][x] = 'B';      
      
      for (int tx = x - 1; tx &lt;= x + 1; ++tx)
        for (int ty = y - 1; ty &lt;= y + 1; ++ty)
          if (tx &gt;= 0 &amp;&amp; tx &lt; n &amp;&amp; ty &gt;= 0 &amp;&amp; ty &lt; m)
            dfs(tx, ty);
    };
    int x = click[1];
    int y = click[0];
    dfs(x, y);
    if (board[y][x] == 'M') board[y][x] = 'X';
    return board;
  }
};</pre>
</div></div>



<h2 class="wp-block-heading"><strong>Solution 2: BFS</strong></h2>



<div class="responsive-tabs">
<h2 class="tabtitle">Python3</h2>
<div class="tabcontent">

<pre class="urvanov-syntax-highlighter-plain-tag"># Author: Huahua
class Solution:
  def updateBoard(self, board: List[List[str]], click: List[int]) -&gt; List[List[str]]:
    m, n = len(board), len(board[0])
    cx, cy = click[1], click[0] 
    q = [(cx, cy)]
    while q:
      q2 = []
      for x, y in q:        
        if board[y][x] != 'E': continue
        c = 0
        for tx in range(x - 1, x + 2):
          for ty in range(y - 1, y + 2):
            if 0 &lt;= tx &lt; n and 0 &lt;= ty &lt; m and board[ty][tx] == 'M':
              c += 1
        if c &gt; 0:
          board[y][x] = chr(ord('0') + c)
          continue
        board[y][x] = 'B'
        for tx in range(x - 1, x + 2):
          for ty in range(y - 1, y + 2):
            if 0 &lt;= tx &lt; n and 0 &lt;= ty &lt; m and board[ty][tx] == 'E':
              q2.append((tx, ty))              
      q = q2
    if board[cy][cx] == 'M': board[y][x] = 'X'
    return board</pre>
</div></div>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-529-minesweeper/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1293. Shortest Path in a Grid with Obstacles Elimination</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1293-shortest-path-in-a-grid-with-obstacles-elimination/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1293-shortest-path-in-a-grid-with-obstacles-elimination/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 15 Dec 2019 04:19:11 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[shortest path]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=5966</guid>

					<description><![CDATA[iven a&#160;m * n&#160;grid, where each cell is either&#160;0&#160;(empty)&#160;or&#160;1&#160;(obstacle).&#160;In one step, you can move up, down, left or right from and to an empty cell.&#8230;]]></description>
										<content:encoded><![CDATA[
<p>iven a&nbsp;<code>m * n</code>&nbsp;grid, where each cell is either&nbsp;<code>0</code>&nbsp;(empty)&nbsp;or&nbsp;<code>1</code>&nbsp;(obstacle).&nbsp;In one step, you can move up, down, left or right from and to an empty cell.</p>



<p>Return the minimum number of steps to walk from the upper left corner&nbsp;<code>(0, 0)</code>&nbsp;to the lower right corner&nbsp;<code>(m-1, n-1)</code>&nbsp;given that you can eliminate&nbsp;<strong>at most</strong>&nbsp;<code>k</code>&nbsp;obstacles. If it is not possible to find such&nbsp;walk return -1.</p>



<p><strong>Example 1:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> 
grid = 
[[0,0,0],
&nbsp;[1,1,0],
 [0,0,0],
&nbsp;[0,1,1],
 [0,0,0]], 
k = 1
<strong>Output:</strong> 6
<strong>Explanation: 
</strong>The shortest path without eliminating any obstacle is 10.&nbsp;
The shortest path with one obstacle elimination at position (3,2) is 6. Such path is <code>(0,0) -&gt; (0,1) -&gt; (0,2) -&gt; (1,2) -&gt; (2,2) -&gt; <strong>(3,2)</strong> -&gt; (4,2)</code>.
</pre>



<p><strong>Example 2:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> 
grid = 
[[0,1,1],
&nbsp;[1,1,1],
&nbsp;[1,0,0]], 
k = 1
<strong>Output:</strong> -1
<strong>Explanation: 
</strong>We need to eliminate at least two obstacles to find such a walk.
</pre>



<p><strong>Constraints:</strong></p>



<ul class="wp-block-list"><li><code>grid.length&nbsp;== m</code></li><li><code>grid[0].length&nbsp;== n</code></li><li><code>1 &lt;= m, n &lt;= 40</code></li><li><code>1 &lt;= k &lt;= m*n</code></li><li><code>grid[i][j] == 0&nbsp;<strong>or</strong>&nbsp;1</code></li><li><code>grid[0][0] == grid[m-1][n-1] == 0</code></li></ul>



<h2 class="wp-block-heading"><strong>Solution: BFS</strong></h2>



<p>State: (x, y, k) where k is the number of obstacles along the path.</p>



<p>Time complexity: O(m*n*k)<br>Space complexity: O(m*n*k)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua, 8 ms, 10.5 MB
class Solution {
public:
  int shortestPath(vector&lt;vector&lt;int&gt;&gt;&amp; grid, int k) {
    const vector&lt;int&gt; dirs{0, 1, 0, -1, 0};
    const int n = grid.size();
    const int m = grid[0].size();
    vector&lt;vector&lt;int&gt;&gt; seen(n, vector&lt;int&gt;(m, INT_MAX));
    queue&lt;tuple&lt;int, int, int&gt;&gt; q; 
    int steps = 0;
    q.emplace(0, 0, 0);
    seen[0][0] = 0;
    while (!q.empty()) {
      int size = q.size();
      while (size--) {
        int cx, cy, co;
        tie(cx, cy, co) = q.front(); q.pop();         
        if (cx == m - 1 &amp;&amp; cy == n - 1) return steps;
        for (int i = 0; i &lt; 4; ++i) {
          int x = cx + dirs[i];
          int y = cy + dirs[i + 1];
          if (x &lt; 0 || y &lt; 0 || x &gt;= m || y &gt;= n) continue;
          int o = co + grid[y][x];
          if (o &gt;= seen[y][x] || o &gt; k) continue;            
          seen[y][x] = o;
          q.emplace(x, y, o);
        }
      }
      ++steps;
    }
    return -1;
  }
};</pre>
</div></div>



<h2 class="wp-block-heading"><strong>Solution 2: DP</strong></h2>



<p>Time complexity: O(mnk)<br>Space complexity: O(mnk)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">Bottom-Up</h2>
<div class="tabcontent">

<pre class="urvanov-syntax-highlighter-plain-tag">// AC 236 ms
class Solution {
public:
  int shortestPath(vector&lt;vector&lt;int&gt;&gt;&amp; grid, int k) {
    constexpr int kInf = 1e9;
    const int m = grid.size();
    const int n = grid[0].size();
    vector&lt;vector&lt;vector&lt;int&gt;&gt;&gt; dp(m + 2, vector&lt;vector&lt;int&gt;&gt;(n + 2, vector&lt;int&gt;(k + 1, kInf)));
    dp[1][1][0] = 0;
    for (int s = 0; s &lt; 3; ++s)
      for (int i = 1; i &lt;= m; ++i)
        for (int j = 1; j &lt;= n; ++j) {
          const int o = grid[i - 1][j - 1];
          for (int z = 0; z + o &lt;= k; ++z)
            dp[i][j][z + o] = min(dp[i][j][z + o],
                                  min({dp[i - 1][j][z],
                                       dp[i][j - 1][z],
                                       dp[i + 1][j][z],
                                       dp[i][j + 1][z]}) + 1);
        }
    int ans = *min_element(begin(dp[m][n]), end(dp[m][n]));
    return ans &gt;= kInf ? -1 : ans;
  }
};</pre>

</div><h2 class="tabtitle">Top-Down</h2>
<div class="tabcontent">

<pre class="urvanov-syntax-highlighter-plain-tag">class Solution {
public:
  int shortestPath(vector&lt;vector&lt;int&gt;&gt;&amp; grid, int K) {
    constexpr int kInf = 1e9;
    const vector&lt;int&gt; dirs{0, 1, 0, -1, 0};
    const int m = grid.size();
    const int n = grid[0].size();
    vector&lt;vector&lt;vector&lt;int&gt;&gt;&gt; mem(m + 2, vector&lt;vector&lt;int&gt;&gt;(n + 2, vector&lt;int&gt;(K + 1, -1)));
    vector&lt;vector&lt;int&gt;&gt; seen(m + 2, vector&lt;int&gt;(n + 2));    
    function&lt;int(int, int, int)&gt; dp = [&amp;](int x, int y, int k) {      
      if (x &lt; 1 || x &gt; n || y &lt; 1 || y &gt; m || k &lt; 0 || seen[y][x]) return kInf;
      if (x == 1 &amp;&amp; y == 1) return 0;
      if (mem[y][x][k] != -1) return mem[y][x][k];
      seen[y][x] = 1;
      int ans = kInf;
      for (int i = 0; i &lt; 4; ++i)
        ans = min(ans, 1 + dp(x + dirs[i], y + dirs[i + 1], k - grid[y - 1][x - 1]));
      seen[y][x] = 0;      
      return mem[y][x][k] = ans;
    };        
    const int ans = dp(n, m, K);
    return ans &gt;= kInf ? -1 : ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1293-shortest-path-in-a-grid-with-obstacles-elimination/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1277. Count Square Submatrices with All Ones</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1277-count-square-submatrices-with-all-ones/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1277-count-square-submatrices-with-all-ones/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 02 Dec 2019 07:21:33 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[ones]]></category>
		<category><![CDATA[square]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=5912</guid>

					<description><![CDATA[Given a&#160;m * n&#160;matrix of ones and zeros, return how many&#160;square&#160;submatrices have all ones. Example 1: Input: matrix = [ &#160; [0,1,1,1], &#160; [1,1,1,1], &#160;&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Given a&nbsp;<code>m * n</code>&nbsp;matrix of ones and zeros, return how many&nbsp;<strong>square</strong>&nbsp;submatrices have all ones.</p>



<p><strong>Example 1:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> matrix =
[
&nbsp; [0,1,1,1],
&nbsp; [1,1,1,1],
&nbsp; [0,1,1,1]
]
<strong>Output:</strong> 15
<strong>Explanation:</strong> 
There are <strong>10</strong> squares of side 1.
There are <strong>4</strong> squares of side 2.
There is  <strong>1</strong> square of side 3.
Total number of squares = 10 + 4 + 1 = <strong>15</strong>.
</pre>



<p><strong>Example 2:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> matrix = 
[
  [1,0,1],
  [1,1,0],
  [1,1,0]
]
<strong>Output:</strong> 7
<strong>Explanation:</strong> 
There are <strong>6</strong> squares of side 1.  
There is <strong>1</strong> square of side 2. 
Total number of squares = 6 + 1 = <strong>7</strong>.
</pre>



<p><strong>Constraints:</strong></p>



<ul class="wp-block-list"><li><code>1 &lt;= arr.length&nbsp;&lt;= 300</code></li><li><code>1 &lt;= arr[0].length&nbsp;&lt;= 300</code></li><li><code>0 &lt;= arr[i][j] &lt;= 1</code></li></ul>



<h2 class="wp-block-heading"><strong>Solution: DP</strong></h2>



<p>dp[i][j] := edge of largest square with bottom right corner at (i, j)<br>dp[i][j] = min(dp[i &#8211; 1][j], dp[i &#8211; 1][j &#8211; 1], dp[i][j &#8211; 1]) if m[i][j] == 1 else 0<br>ans = sum(dp)</p>



<p>Time complexity: O(n*m)<br>Space complexity: O(n*m)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  int countSquares(vector&lt;vector&lt;int&gt;&gt;&amp; matrix) {
    const int n = matrix.size();
    const int m = matrix[0].size();
    // dp[i][j] := edge of largest square with right bottom corner at (i, j)
    vector&lt;vector&lt;int&gt;&gt; dp(n, vector&lt;int&gt;(m));
    int ans = 0;
    for (int i = 0; i &lt; n; ++i)
      for (int j = 0; j &lt; m; ++j) {
        dp[i][j] = matrix[i][j];
        if (i &amp;&amp; j &amp;&amp; dp[i][j])
          dp[i][j] = min({dp[i - 1][j - 1], dp[i][j - 1], dp[i - 1][j]}) + 1;
        ans += dp[i][j];
      }
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1277-count-square-submatrices-with-all-ones/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1267. Count Servers that Communicate</title>
		<link>https://zxi.mytechroad.com/blog/algorithms/array/leetcode-1267-count-servers-that-communicate/</link>
					<comments>https://zxi.mytechroad.com/blog/algorithms/array/leetcode-1267-count-servers-that-communicate/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 24 Nov 2019 07:47:55 +0000</pubDate>
				<category><![CDATA[Array]]></category>
		<category><![CDATA[counting]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[O(mn)]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=5837</guid>

					<description><![CDATA[You are given a map of a server center, represented as a&#160;m * n&#160;integer matrix&#160;grid, where 1 means that on that cell there is a&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You are given a map of a server center, represented as a&nbsp;<code>m * n</code>&nbsp;integer matrix&nbsp;<code>grid</code>, where 1 means that on that cell there is a server and 0 means that it is no server. Two servers are said to communicate if they are on the same row or on the same column.<br><br>Return the number of servers&nbsp;that communicate with any other server.</p>



<p><strong>Example 1:</strong></p>



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2019/11/14/untitled-diagram-6.jpg" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> grid = [[1,0],[0,1]]
<strong>Output:</strong> 0
<strong>Explanation:</strong>&nbsp;No servers can communicate with others.</pre>



<p><strong>Example 2:</strong></p>



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2019/11/13/untitled-diagram-4.jpg" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> grid = [[1,0],[1,1]]
<strong>Output:</strong> 3
<strong>Explanation:</strong>&nbsp;All three servers can communicate with at least one other server.
</pre>



<p><strong>Example 3:</strong></p>



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2019/11/14/untitled-diagram-1-3.jpg" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> grid = [[1,1,0,0],[0,0,1,0],[0,0,1,0],[0,0,0,1]]
<strong>Output:</strong> 4
<strong>Explanation:</strong>&nbsp;The two servers in the first row can communicate with each other. The two servers in the third column can communicate with each other. The server at right bottom corner can't communicate with any other server.
</pre>



<p><strong>Constraints:</strong></p>



<ul class="wp-block-list"><li><code>m == grid.length</code></li><li><code>n == grid[i].length</code></li><li><code>1 &lt;= m &lt;= 250</code></li><li><code>1 &lt;= n &lt;= 250</code></li><li><code>grid[i][j] == 0 or 1</code></li></ul>



<h2 class="wp-block-heading"><strong>Solution: Counting</strong></h2>



<p>Two passes:<br>First pass, count number of computers for each row and each column. <br>Second pass, count grid[i][j] if rows[i] or cols[j] has more than 1 computer.</p>



<p>Time complexity: O(m*n)<br>Space complexity: O(m + n)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  int countServers(vector&lt;vector&lt;int&gt;&gt;&amp; grid) {
    const size_t m = grid.size();
    const size_t n = grid[0].size();
    vector&lt;int&gt; rows(m);
    vector&lt;int&gt; cols(n);
    for (size_t i = 0; i &lt; m; ++i)
      for (size_t j = 0; j &lt; n; ++j) {
        rows[i] += grid[i][j];
        cols[j] += grid[i][j];
      }
    int ans = 0;
     for (size_t i = 0; i &lt; m; ++i)
      for (size_t j = 0; j &lt; n; ++j)
        ans += (rows[i] &gt; 1 || cols[j] &gt; 1) ? grid[i][j] : 0;
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/algorithms/array/leetcode-1267-count-servers-that-communicate/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1219. Path with Maximum Gold</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-1219-path-with-maximum-gold/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-1219-path-with-maximum-gold/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 06 Oct 2019 04:35:35 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[medium]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=5718</guid>

					<description><![CDATA[In a gold mine&#160;grid&#160;of size&#160;m * n,&#160;each cell in this mine has an integer representing the amount of gold&#160;in that cell,&#160;0&#160;if it is empty. Return&#8230;]]></description>
										<content:encoded><![CDATA[
<p>In a gold mine&nbsp;<code>grid</code>&nbsp;of size&nbsp;<code>m * n</code>,&nbsp;each cell in this mine has an integer representing the amount of gold&nbsp;in that cell,&nbsp;<code>0</code>&nbsp;if it is empty.</p>



<p>Return the maximum amount of gold you&nbsp;can collect under the conditions:</p>



<ul class="wp-block-list"><li>Every time you are located in a cell you will collect all the gold in that cell.</li><li>From your position you can walk one step to the left, right, up or down.</li><li>You can&#8217;t visit the same cell more than once.</li><li>Never visit a cell with&nbsp;<code>0</code>&nbsp;gold.</li><li>You can start and stop collecting gold from&nbsp;<strong>any&nbsp;</strong>position in the grid that has some gold.</li></ul>



<p><strong>Example 1:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> grid = [[0,6,0],[5,8,7],[0,9,0]]
<strong>Output:</strong> 24
<strong>Explanation:</strong>
[[0,6,0],
 [5,8,7],
 [0,9,0]]
Path to get the maximum gold, 9 -&gt; 8 -&gt; 7.
</pre>



<p><strong>Example 2:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> grid = [[1,0,7],[2,0,6],[3,4,5],[0,3,0],[9,0,20]]
<strong>Output:</strong> 28
<strong>Explanation:</strong>
[[1,0,7],
 [2,0,6],
 [3,4,5],
 [0,3,0],
 [9,0,20]]
Path to get the maximum gold, 1 -&gt; 2 -&gt; 3 -&gt; 4 -&gt; 5 -&gt; 6 -&gt; 7.
</pre>



<p><strong>Constraints:</strong></p>



<ul class="wp-block-list"><li><code>1 &lt;= grid.length,&nbsp;grid[i].length &lt;= 15</code></li><li><code>0 &lt;= grid[i][j] &lt;= 100</code></li><li>There are at most&nbsp;<strong>25&nbsp;</strong>cells containing gold.</li></ul>



<h2 class="wp-block-heading"><strong>Solution: DFS</strong></h2>



<p>Time compleixty: O(4^25) ???<br>Space complexity: O(25)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  int getMaximumGold(vector&lt;vector&lt;int&gt;&gt;&amp; g) {
    int n = g.size();
    int m = g[0].size();
    int ans = 0;
    function&lt;int(int, int)&gt; dfs = [&amp;](int x, int y) {
      if (x &lt; 0 || x &gt;= m || y &lt; 0 || y &gt;= n || g[y][x] == 0) return 0;
      int c = 0;
      swap(c, g[y][x]);
      int r = c + max({dfs(x - 1, y), dfs(x + 1, y), dfs(x, y - 1), dfs(x, y + 1)});
      swap(c, g[y][x]);
      return r;
    };
    for (int i = 0; i &lt; n; ++i) 
      for (int j = 0; j &lt; m; ++j)        
        ans = max(ans, dfs(j, i));
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-1219-path-with-maximum-gold/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1139. Largest 1-Bordered Square</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1139-largest-1-bordered-square/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1139-largest-1-bordered-square/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 28 Jul 2019 05:01:54 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[2D]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[medium]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=5364</guid>

					<description><![CDATA[Given a 2D&#160;grid&#160;of&#160;0s and&#160;1s, return the number of elements in&#160;the largest&#160;square&#160;subgrid that has all&#160;1s on its&#160;border, or&#160;0&#160;if such a subgrid&#160;doesn&#8217;t exist in the&#160;grid. Example 1:&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Given a 2D&nbsp;<code>grid</code>&nbsp;of&nbsp;<code>0</code>s and&nbsp;<code>1</code>s, return the number of elements in&nbsp;the largest&nbsp;<strong>square</strong>&nbsp;subgrid that has all&nbsp;<code>1</code>s on its&nbsp;<strong>border</strong>, or&nbsp;<code>0</code>&nbsp;if such a subgrid&nbsp;doesn&#8217;t exist in the&nbsp;<code>grid</code>.</p>



<p><strong>Example 1:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> grid = [[1,1,1],[1,0,1],[1,1,1]]
<strong>Output:</strong> 9
</pre>



<p><strong>Example 2:</strong></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> grid = [[1,1,0,0]]
<strong>Output:</strong> 1
</pre>



<p><strong>Constraints:</strong></p>



<ul class="wp-block-list"><li><code>1 &lt;= grid.length &lt;= 100</code></li><li><code>1 &lt;= grid[0].length &lt;= 100</code></li><li><code>grid[i][j]</code>&nbsp;is&nbsp;<code>0</code>&nbsp;or&nbsp;<code>1</code></li></ul>



<h2 class="wp-block-heading"><strong>Solution: DP</strong></h2>



<p>Compute the sums of all rectangles that has left-top corner at (0, 0) in O(m*n) time. <br>For each square and check whether its borders are all ones in O(1) time.</p>



<p>Time complexity: O(m*n*min(m,n))<br>Space complexity: O(m*n)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  int largest1BorderedSquare(vector&lt;vector&lt;int&gt;&gt;&amp; grid) {
    int n = grid.size();
    int m = grid[0].size();
    vector&lt;vector&lt;int&gt;&gt; dp(n + 1, vector&lt;int&gt;(m + 1));
    for (int i = 1; i &lt;= n; ++i)
      for (int j = 1; j &lt;= m; ++j)
        dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1] + grid[i - 1][j - 1];
    
    for (int len = min(n, m); len &gt; 0; --len)
      for (int x1 = 1, x2 = x1 + len - 1; x2 &lt;= m; ++x1, ++x2)
        for (int y1 = 1, y2 = y1 + len - 1; y2 &lt;= n; ++y1, ++y2)
          if (getArea(x1, y1, x2, y1, dp) == len 
              &amp;&amp; getArea(x1, y1, x1, y2, dp) == len
              &amp;&amp; getArea(x1, y2, x2, y2, dp) == len
              &amp;&amp; getArea(x2, y1, x2, y2, dp) == len)            
            return len * len;        
    return 0;
  }
private:
  int getArea(int x1, int y1, int x2, int y2, const vector&lt;vector&lt;int&gt;&gt;&amp; dp) {
    return dp[y2][x2] - dp[y2][x1 - 1] - dp[y1 - 1][x2] + dp[y1 - 1][x1 - 1];
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1139-largest-1-bordered-square/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 994. Rotting Oranges</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-994-rotting-oranges/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-994-rotting-oranges/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 17 Feb 2019 07:37:10 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[BFS]]></category>
		<category><![CDATA[easy]]></category>
		<category><![CDATA[grid]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=4862</guid>

					<description><![CDATA[In a given grid, each cell can have one of three&#160;values: the value&#160;0&#160;representing an empty cell; the value&#160;1&#160;representing a fresh orange; the value&#160;2&#160;representing a rotten&#8230;]]></description>
										<content:encoded><![CDATA[
<p>In a given grid, each cell can have one of three&nbsp;values:</p>



<ul class="wp-block-list"><li>the value&nbsp;<code>0</code>&nbsp;representing an empty cell;</li><li>the value&nbsp;<code>1</code>&nbsp;representing a fresh orange;</li><li>the value&nbsp;<code>2</code>&nbsp;representing a rotten orange.</li></ul>



<p>Every minute, any fresh orange that is adjacent (4-directionally) to a rotten orange becomes rotten.</p>



<p>Return the minimum number of minutes that must elapse until no cell has a fresh orange.&nbsp; If this is impossible, return&nbsp;<code>-1</code>instead.</p>



<p><strong>Example 1:</strong></p>



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2019/02/16/oranges.png" alt=""/></figure>



<pre class="wp-block-preformatted crayon:false"><strong>Input: </strong>[[2,1,1],[1,1,0],[0,1,1]]
<strong>Output: </strong>4
</pre>



<p><strong>Example 2:</strong></p>



<pre class="wp-block-preformatted crayon:false"><strong>Input: </strong>[[2,1,1],[0,1,1],[1,0,1]]
<strong>Output: </strong>-1
<strong>Explanation: </strong> The orange in the bottom left corner (row 2, column 0) is never rotten, because rotting only happens 4-directionally.
</pre>



<p><strong>Example 3:</strong></p>



<pre class="wp-block-preformatted crayon:false"><strong>Input: </strong>[[0,2]]
<strong>Output: </strong>0
<strong>Explanation: </strong> Since there are already no fresh oranges at minute 0, the answer is just 0.
</pre>



<p><strong>Note:</strong></p>



<ol class="wp-block-list"><li><code>1 &lt;= grid.length &lt;= 10</code></li><li><code>1 &lt;= grid[0].length &lt;= 10</code></li><li><code>grid[i][j]</code>&nbsp;is only&nbsp;<code>0</code>,&nbsp;<code>1</code>, or&nbsp;<code>2</code>.</li></ol>



<h2 class="wp-block-heading"><strong>Solution:&nbsp;BFS</strong></h2>



<p>Time complexity: O(mn)<br>Space complexity: O(mn)</p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua, Running time: 12 ms, 10.8 MB
class Solution {
public:
  int orangesRotting(vector&lt;vector&lt;int&gt;&gt;&amp; grid) {
    const int m = grid.size();
    const int n = grid[0].size();
    queue&lt;pair&lt;int,int&gt;&gt; q;
    int fresh = 0;
    for (int i = 0; i &lt; m; ++i)
      for (int j = 0; j &lt; n; ++j)
        if (grid[i][j] == 1) ++fresh;
        else if (grid[i][j] == 2) q.emplace(j, i);
    vector&lt;int&gt; dirs = {1, 0, -1, 0, 1};    
    int days = 0;
    while (!q.empty() &amp;&amp; fresh) {
      int size = q.size();
      while (size--) {
        int x = q.front().first;
        int y = q.front().second;
        q.pop();
        for (int i = 0; i &lt; 4; ++i) {
          int dx = x + dirs[i];
          int dy = y + dirs[i + 1];
          if (dx &lt; 0 || dx &gt;= n || dy &lt; 0 || dy &gt;= m || grid[dy][dx] != 1) continue;
          --fresh;
          grid[dy][dx] = 2;
          q.emplace(dx, dy);
        }
      }
      ++days;
    }    
    return fresh ? -1 : days;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-994-rotting-oranges/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 85. Maximal Rectangle</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-85-maximal-rectangle/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-85-maximal-rectangle/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 26 Jan 2019 18:21:08 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[2D]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[rectangle]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=4686</guid>

					<description><![CDATA[Given a 2D binary matrix filled with 0&#8217;s and 1&#8217;s, find the largest rectangle containing only 1&#8217;s and return its area. Example: Input: [ ["1","0","1","0","0"],&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Given a 2D binary matrix filled with 0&#8217;s and 1&#8217;s, find the largest rectangle containing only 1&#8217;s and return its area.</p>



<p><strong>Example:</strong></p>



<pre class="wp-block-preformatted crayon:false"><strong>Input:</strong>
[
  ["1","0","1","0","0"],
  ["1","0","<strong>1</strong>","<strong>1</strong>","<strong>1</strong>"],
  ["1","1","<strong>1</strong>","<strong>1</strong>","<strong>1</strong>"],
  ["1","0","0","1","0"]
]
<strong>Output:</strong> 6</pre>



<h2 class="wp-block-heading">Solution: DP</h2>



<p>Time complexity: O(m^2*n)<br>Space complexity: O(mn)</p>



<p>dp[i][j] := max length of all 1 sequence ends with col j, at the i-th row.<br>transition: <br>dp[i][j] = 0 if matrix[i][j] == &#8216;0&#8217;<br>             = dp[i][j-1] + 1 if  matrix[i][j] == &#8216;1&#8217; </p>



<div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">

<pre class="urvanov-syntax-highlighter-plain-tag">class Solution {
public:
  int maximalRectangle(vector&lt;vector&lt;char&gt; &gt; &amp;matrix) {
    int r = matrix.size();
    if (r == 0) return 0;
    int c = matrix[0].size();
  
    // dp[i][j] := max len of all 1s ends with col j at row i.
    vector&lt;vector&lt;int&gt;&gt; dp(r, vector&lt;int&gt;(c));

    for (int i = 0; i &lt; r; ++i)
      for (int j = 0; j &lt; c; ++j)
        dp[i][j] = (matrix[i][j] == '1') ? (j == 0 ? 1 : dp[i][j - 1] + 1) : 0;

    int ans = 0;

    for (int i = 0; i &lt; r; ++i)
      for (int j = 0; j &lt; c; ++j) {
        int len = INT_MAX;
        for (int k = i; k &lt; r; k++) {
          len = min(len, dp[k][j]);
          if (len == 0) break;
          ans = max(len * (k - i + 1), ans);
        }
    }

    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-85-maximal-rectangle/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 463. Island Perimeter</title>
		<link>https://zxi.mytechroad.com/blog/math/leetcode-463-island-perimeter/</link>
					<comments>https://zxi.mytechroad.com/blog/math/leetcode-463-island-perimeter/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Fri, 17 Aug 2018 16:25:05 +0000</pubDate>
				<category><![CDATA[Math]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[O(mn)]]></category>
		<category><![CDATA[perimeter]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=3576</guid>

					<description><![CDATA[Problem You are given a map in form of a two-dimensional integer grid where 1 represents land and 0 represents water. Grid cells are connected&#8230;]]></description>
										<content:encoded><![CDATA[<p><iframe loading="lazy" title="花花酱 LeetCode 463. Island Perimeter - 刷题找工作 EP13" width="500" height="375" src="https://www.youtube.com/embed/ddFvTWmVUEA?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></p>
<h1>Problem</h1>
<p>You are given a map in form of a two-dimensional integer grid where 1 represents land and 0 represents water. Grid cells are connected horizontally/vertically (not diagonally). The grid is completely surrounded by water, and there is exactly one island (i.e., one or more connected land cells). The island doesn&#8217;t have &#8220;lakes&#8221; (water inside that isn&#8217;t connected to the water around the island). One cell is a square with side length 1. The grid is rectangular, width and height don&#8217;t exceed 100. Determine the perimeter of the island.</p>
<p><b>Example:</b></p>
<pre class="crayon:false">[[0,1,0,0],
 [1,1,1,0],
 [0,1,0,0],
 [1,1,0,0]]

Answer: 16
Explanation: The perimeter is the 16 yellow stripes in the image below:
<img decoding="async" src="https://leetcode.com/static/images/problemset/island.png" />
</pre>
<h1><strong>Solution: Counting</strong></h1>
<p>If a land has 0 neighbour, it contributes 4 to the perimeter</p>
<p>If a land has 1 neighbour, it contributes 3 to the perimeter</p>
<p>If a land has 2 neighbours, it contributes 2 to the perimeter</p>
<p>If a land has 3 neighbours, it contributes 1 to the perimeter</p>
<p>If a land has 4 neighbours, it contributes 0 to the perimeter</p>
<p>perimeter = area * 4 &#8211; total_neighbours</p>
<p>Time complexity: O(mn)</p>
<p>Space complexity: O(1)</p><pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
// Running time: 148 ms
class Solution {
public:
  int islandPerimeter(vector&lt;vector&lt;int&gt;&gt;&amp; grid) {
    if (grid.empty()) return 0;
    int m = grid.size();
    int n = grid[0].size();
    int area = 0;
    int conn = 0;

    for (int y = 0; y &lt; m; ++y)
      for (int x = 0; x &lt; n; ++x)
        if (grid[y][x] == 1) {
          ++area;
          if (y &gt; 0 &amp;&amp; grid[y - 1][x] == 1) ++conn;
          if (x &gt; 0 &amp;&amp; grid[y][x - 1] == 1) ++conn;
        }

    return area*4 - conn*2;
  }
};</pre><p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/math/leetcode-463-island-perimeter/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 174. Dungeon Game</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-174-dungeon-game/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-174-dungeon-game/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Thu, 16 Aug 2018 15:45:07 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[O(mn)]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=3543</guid>

					<description><![CDATA[Problem The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. The dungeon consists of M x N&#8230;]]></description>
										<content:encoded><![CDATA[<p><iframe loading="lazy" title="花花酱 LeetCode 174. Dungeon Game - 刷题找工作 EP6" width="500" height="375" src="https://www.youtube.com/embed/pt-xIS6huIg?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></p>
<h1><strong>Problem</strong></h1>
<div class="question-description__3U1T">
<p>The demons had captured the princess (<strong>P</strong>) and imprisoned her in the bottom-right corner of a dungeon. The dungeon consists of M x N rooms laid out in a 2D grid. Our valiant knight (<strong>K</strong>) was initially positioned in the top-left room and must fight his way through the dungeon to rescue the princess.</p>
<p>The knight has an initial health point represented by a positive integer. If at any point his health point drops to 0 or below, he dies immediately.</p>
<p>Some of the rooms are guarded by demons, so the knight loses health (<em>negative</em> integers) upon entering these rooms; other rooms are either empty (<em>0&#8217;s</em>) or contain magic orbs that increase the knight&#8217;s health (<em>positive</em> integers).</p>
<p>In order to reach the princess as quickly as possible, the knight decides to move only rightward or downward in each step.</p>
<p><strong>Write a function to determine the knight&#8217;s minimum initial health so that he is able to rescue the princess.</strong></p>
<p>For example, given the dungeon below, the initial health of the knight must be at least <strong>7</strong> if he follows the optimal path <code>RIGHT-&gt; RIGHT -&gt; DOWN -&gt; DOWN</code>.</p>
<table class="dungeon">
<tbody>
<tr>
<td>-2 (K)</td>
<td>-3</td>
<td>3</td>
</tr>
<tr>
<td>-5</td>
<td>-10</td>
<td>1</td>
</tr>
<tr>
<td>10</td>
<td>30</td>
<td>-5 (P)</td>
</tr>
</tbody>
</table>
<p><strong>Note:</strong></p>
<ul>
<li>The knight&#8217;s health has no upper bound.</li>
<li>Any room can contain threats or power-ups, even the first room the knight enters and the bottom-right room where the princess is imprisoned.</li>
</ul>
<h1><strong>Solution: DP</strong></h1>
<p>Time complexity: O(mn)</p>
<p>Space complexity: O(mn) -&gt; O(n)</p>
<p>C++</p><pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
// Running time: 4 ms
class Solution {
public:
  int calculateMinimumHP(vector&lt;vector&lt;int&gt;&gt;&amp; dungeon) {      
    const int m = dungeon.size();
    const int n = dungeon[0].size();

    // hp[y][x]: min hp required to reach bottom right (P).
    vector&lt;vector&lt;int&gt;&gt; hp(m + 1, vector&lt;int&gt;(n + 1, INT_MAX));
    hp[m][n - 1] = hp[m - 1][n] = 1;

    for (int y = m - 1; y &gt;= 0; --y)
      for (int x = n - 1; x &gt;= 0; --x)
        hp[y][x] = max(1, min(hp[y + 1][x], hp[y][x + 1]) - dungeon[y][x]);

    return hp[0][0];
  }
};</pre><p>O(n) space</p><pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
// Running time: 4 ms
class Solution {
public:
  int calculateMinimumHP(vector&lt;vector&lt;int&gt;&gt;&amp; dungeon) {      
    const int m = dungeon.size();
    const int n = dungeon[0].size();

    // hp[y][x]: min hp required to reach bottom right (P).
    vector&lt;int&gt; hp(n + 1, INT_MAX);
    hp[n - 1] = 1;

    for (int y = m - 1; y &gt;= 0; --y)
      for (int x = n - 1; x &gt;= 0; --x)
        hp[x] = max(1, min(hp[x], hp[x + 1]) - dungeon[y][x]);

    return hp[0];
  }
};</pre><p>&nbsp;</p>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-174-dungeon-game/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
