<?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>BFS &#8211; Huahua&#8217;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/tag/bfs/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog</link>
	<description></description>
	<lastBuildDate>Thu, 10 Apr 2025 15:01:46 +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>BFS &#8211; Huahua&#8217;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>花花酱 LeetCode 650. 2 Keys Keyboard</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-650-2-keys-keyboard/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-650-2-keys-keyboard/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Thu, 10 Apr 2025 14:44:47 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[BFS]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[search]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=10307</guid>

					<description><![CDATA[这道题目还是可以的。每个阶段有两种选择，求最短的决策次数。有好多种不同的做法，我们一个一个来。 方法1: BFS 把问题看成求无权重图中的最短路径，BFS可以找到最优解。 我们的节点有两个状态，当前的长度，剪贴板（上次复制后）的长度。长度超过n一定无解，所以我们的状态最多只有n2种，每个状态最多拓展2个新的节点。 时间复杂度：O(n2)空间复杂度：O(n2) [crayon-67ffc90b32685216765037/]]]></description>
										<content:encoded><![CDATA[
<p>这道题目还是可以的。每个阶段有两种选择，求最短的决策次数。有好多种不同的做法，我们一个一个来。</p>



<p>方法1: BFS<br><br>把问题看成求无权重图中的最短路径，BFS可以找到最优解。</p>



<p>我们的节点有两个状态，当前的长度，剪贴板（上次复制后）的长度。<br>长度超过n一定无解，所以我们的状态最多只有n<sup>2</sup>种，每个状态最多拓展2个新的节点。</p>



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



<p>时间复杂度：O(n<sup>2</sup>)<br>空间复杂度：O(n<sup>2</sup>)</p>



<pre class="urvanov-syntax-highlighter-plain-tag">class Solution {
public:
  int minSteps(int n) {
    vector&lt;vector&lt;bool&gt;&gt; seen(n + 1, vector&lt;bool&gt;(n + 1));
    queue&lt;pair&lt;int, int&gt;&gt; q;

    auto expand = [&amp;](int len, int clip) {
      if (len &gt; n || len &gt; n || seen[len][clip]) return;
      q.emplace(len, clip);
      seen[len][clip] = true;
    };

    int steps = 0;
    expand(1, 0); // init state.
    while (!q.empty()) {
      int size = q.size();
      while (size--) {
        auto [len, clip] = q.front(); q.pop();
        if (len == n) return steps;
        expand(len, len); // copy.
        expand(len + clip, clip); // paste.
      }
      ++steps;
    }
    return -1;
  }
};</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-650-2-keys-keyboard/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 1926. Nearest Exit from Entrance in Maze</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-1926-nearest-exit-from-entrance-in-maze/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-1926-nearest-exit-from-entrance-in-maze/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Thu, 30 Dec 2021 11:07:41 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[BFS]]></category>
		<category><![CDATA[shortest path]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9285</guid>

					<description><![CDATA[You are given an&#160;m x n&#160;matrix&#160;maze&#160;(0-indexed) with empty cells (represented as&#160;'.') and walls (represented as&#160;'+'). You are also given the&#160;entrance&#160;of the maze, where&#160;entrance = [entrancerow,&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You are given an&nbsp;<code>m x n</code>&nbsp;matrix&nbsp;<code>maze</code>&nbsp;(<strong>0-indexed</strong>) with empty cells (represented as&nbsp;<code>'.'</code>) and walls (represented as&nbsp;<code>'+'</code>). You are also given the&nbsp;<code>entrance</code>&nbsp;of the maze, where&nbsp;<code>entrance = [entrance<sub>row</sub>, entrance<sub>col</sub>]</code>&nbsp;denotes the row and column of the cell you are initially standing at.</p>



<p>In one step, you can move one cell&nbsp;<strong>up</strong>,&nbsp;<strong>down</strong>,&nbsp;<strong>left</strong>, or&nbsp;<strong>right</strong>. You cannot step into a cell with a wall, and you cannot step outside the maze. Your goal is to find the&nbsp;<strong>nearest exit</strong>&nbsp;from the&nbsp;<code>entrance</code>. An&nbsp;<strong>exit</strong>&nbsp;is defined as an&nbsp;<strong>empty cell</strong>&nbsp;that is at the&nbsp;<strong>border</strong>&nbsp;of the&nbsp;<code>maze</code>. The&nbsp;<code>entrance</code>&nbsp;<strong>does not count</strong>&nbsp;as an exit.</p>



<p>Return&nbsp;<em>the&nbsp;<strong>number of steps</strong>&nbsp;in the shortest path from the&nbsp;</em><code>entrance</code><em>&nbsp;to the nearest exit, or&nbsp;</em><code>-1</code><em>&nbsp;if no such path exists</em>.</p>



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



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2021/06/04/nearest1-grid.jpg" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> maze = [["+","+",".","+"],[".",".",".","+"],["+","+","+","."]], entrance = [1,2]
<strong>Output:</strong> 1
<strong>Explanation:</strong> There are 3 exits in this maze at [1,0], [0,2], and [2,3].
Initially, you are at the entrance cell [1,2].
- You can reach [1,0] by moving 2 steps left.
- You can reach [0,2] by moving 1 step up.
It is impossible to reach [2,3] from the entrance.
Thus, the nearest exit is [0,2], which is 1 step away.
</pre>



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



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2021/06/04/nearesr2-grid.jpg" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> maze = [["+","+","+"],[".",".","."],["+","+","+"]], entrance = [1,0]
<strong>Output:</strong> 2
<strong>Explanation:</strong> There is 1 exit in this maze at [1,2].
[1,0] does not count as an exit since it is the entrance cell.
Initially, you are at the entrance cell [1,0].
- You can reach [1,2] by moving 2 steps right.
Thus, the nearest exit is [1,2], which is 2 steps away.
</pre>



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



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2021/06/04/nearest3-grid.jpg" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> maze = [[".","+"]], entrance = [0,0]
<strong>Output:</strong> -1
<strong>Explanation:</strong> There are no exits in this maze.
</pre>



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



<ul class="wp-block-list"><li><code>maze.length == m</code></li><li><code>maze[i].length == n</code></li><li><code>1 &lt;= m, n &lt;= 100</code></li><li><code>maze[i][j]</code>&nbsp;is either&nbsp;<code>'.'</code>&nbsp;or&nbsp;<code>'+'</code>.</li><li><code>entrance.length == 2</code></li><li><code>0 &lt;= entrance<sub>row</sub>&nbsp;&lt; m</code></li><li><code>0 &lt;= entrance<sub>col</sub>&nbsp;&lt; n</code></li><li><code>entrance</code>&nbsp;will always be an empty cell.</li></ul>



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



<p>Use BFS to find the shortest path. We can re-use the board for visited array.</p>



<p>Time complexity: O(m*n)<br>Space complexity: O(1)</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 nearestExit(vector&lt;vector&lt;char&gt;&gt;&amp; maze, vector&lt;int&gt;&amp; entrance) {    
    const int m = maze.size();
    const int n = maze[0].size();
    const vector&lt;int&gt; dirs{0, -1, 0, 1, 0};
    queue&lt;pair&lt;int, int&gt;&gt; q;
    q.emplace(entrance[1], entrance[0]);    
    for (int steps = 0; !q.empty(); ++steps) {      
      for (int s = q.size(); s; --s) {      
        const auto [x, y] = q.front(); q.pop();        
        if (x == 0 || x == n - 1 || y == 0 || y == m - 1)
          if (x != entrance[1] || y != entrance[0])
            return steps;
        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 || maze[ty][tx] != '.') continue;
          maze[ty][tx] = '*';
          q.emplace(tx, ty);
        }
      }      
    }
    return -1;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-1926-nearest-exit-from-entrance-in-maze/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2101. Detonate the Maximum Bombs</title>
		<link>https://zxi.mytechroad.com/blog/simulation/leetcode-2101-detonate-the-maximum-bombs/</link>
					<comments>https://zxi.mytechroad.com/blog/simulation/leetcode-2101-detonate-the-maximum-bombs/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 12 Dec 2021 21:04:14 +0000</pubDate>
				<category><![CDATA[Simulation]]></category>
		<category><![CDATA[BFS]]></category>
		<category><![CDATA[geometry]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[simulation]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9139</guid>

					<description><![CDATA[You are given a list of bombs. The&#160;range&#160;of a bomb is defined as the area where its effect can be felt. This area is in&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You are given a list of bombs. The&nbsp;<strong>range</strong>&nbsp;of a bomb is defined as the area where its effect can be felt. This area is in the shape of a&nbsp;<strong>circle</strong>&nbsp;with the center as the location of the bomb.</p>



<p>The bombs are represented by a&nbsp;<strong>0-indexed</strong>&nbsp;2D integer array&nbsp;<code>bombs</code>&nbsp;where&nbsp;<code>bombs[i] = [x<sub>i</sub>, y<sub>i</sub>, r<sub>i</sub>]</code>.&nbsp;<code>x<sub>i</sub></code>&nbsp;and&nbsp;<code>y<sub>i</sub></code>&nbsp;denote the X-coordinate and Y-coordinate of the location of the&nbsp;<code>i<sup>th</sup></code>&nbsp;bomb, whereas&nbsp;<code>r<sub>i</sub></code>&nbsp;denotes the&nbsp;<strong>radius</strong>&nbsp;of its range.</p>



<p>You may choose to detonate a&nbsp;<strong>single</strong>&nbsp;bomb. When a bomb is detonated, it will detonate&nbsp;<strong>all bombs</strong>&nbsp;that lie in its range. These bombs will further detonate the bombs that lie in their ranges.</p>



<p>Given the list of&nbsp;<code>bombs</code>, return&nbsp;<em>the&nbsp;<strong>maximum</strong>&nbsp;number of bombs that can be detonated if you are allowed to detonate&nbsp;<strong>only one</strong>&nbsp;bomb</em>.</p>



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



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2021/11/06/desmos-eg-3.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> bombs = [[2,1,3],[6,1,4]]
<strong>Output:</strong> 2
<strong>Explanation:</strong>
The above figure shows the positions and ranges of the 2 bombs.
If we detonate the left bomb, the right bomb will not be affected.
But if we detonate the right bomb, both bombs will be detonated.
So the maximum bombs that can be detonated is max(1, 2) = 2.
</pre>



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



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2021/11/06/desmos-eg-2.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> bombs = [[1,1,5],[10,10,5]]
<strong>Output:</strong> 1
<strong>Explanation:
</strong>Detonating either bomb will not detonate the other bomb, so the maximum number of bombs that can be detonated is 1.
</pre>



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



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2021/11/07/desmos-eg1.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> bombs = [[1,2,3],[2,3,1],[3,4,2],[4,5,3],[5,6,4]]
<strong>Output:</strong> 5
<strong>Explanation:</strong>
The best bomb to detonate is bomb 0 because:
- Bomb 0 detonates bombs 1 and 2. The red circle denotes the range of bomb 0.
- Bomb 2 detonates bomb 3. The blue circle denotes the range of bomb 2.
- Bomb 3 detonates bomb 4. The green circle denotes the range of bomb 3.
Thus all 5 bombs are detonated.
</pre>



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



<ul class="wp-block-list"><li><code>1 &lt;= bombs.length&nbsp;&lt;= 100</code></li><li><code>bombs[i].length == 3</code></li><li><code>1 &lt;= x<sub>i</sub>, y<sub>i</sub>, r<sub>i</sub>&nbsp;&lt;= 10<sup>5</sup></code></li></ul>



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



<p>Enumerate the bomb to detonate, and simulate the process using BFS.</p>



<p>Time complexity: O(n<sup>3</sup>)<br>Space complexity: O(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 maximumDetonation(vector&lt;vector&lt;int&gt;&gt;&amp; bombs) {
    const int n = bombs.size();    
    auto check = [&amp;](int i, int j) -&gt; bool {
      long x1 = bombs[i][0], y1 = bombs[i][1], r1 = bombs[i][2];
      long x2 = bombs[j][0], y2 = bombs[j][1], r2 = bombs[j][2];
      return ((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) &lt;= r1 * r1);          
    };
    int ans = 0;
    for (int s = 0; s &lt; n; ++s) {
      int count = 0;
      queue&lt;int&gt; q{{s}};
      vector&lt;int&gt; seen(n);
      seen[s] = 1;
      while (!q.empty()) {
        ++count;
        int i = q.front(); q.pop();
        for (int j = 0; j &lt; n; ++j)
          if (check(i, j) &amp;&amp; !seen[j]++)
            q.push(j);
      }
      ans = max(ans, count);
    }
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/simulation/leetcode-2101-detonate-the-maximum-bombs/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2059. Minimum Operations to Convert Number</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-2059-minimum-operations-to-convert-number/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-2059-minimum-operations-to-convert-number/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Fri, 05 Nov 2021 06:00:14 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[BFS]]></category>
		<category><![CDATA[medium]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8666</guid>

					<description><![CDATA[You are given a&#160;0-indexed&#160;integer array&#160;nums&#160;containing&#160;distinct&#160;numbers, an integer&#160;start, and an integer&#160;goal. There is an integer&#160;x&#160;that is initially set to&#160;start, and you want to perform operations on&#160;x&#160;such&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You are given a&nbsp;<strong>0-indexed</strong>&nbsp;integer array&nbsp;<code>nums</code>&nbsp;containing&nbsp;<strong>distinct</strong>&nbsp;numbers, an integer&nbsp;<code>start</code>, and an integer&nbsp;<code>goal</code>. There is an integer&nbsp;<code>x</code>&nbsp;that is initially set to&nbsp;<code>start</code>, and you want to perform operations on&nbsp;<code>x</code>&nbsp;such that it is converted to&nbsp;<code>goal</code>. You can perform the following operation repeatedly on the number&nbsp;<code>x</code>:</p>



<p>If&nbsp;<code>0 &lt;= x &lt;= 1000</code>, then for any index&nbsp;<code>i</code>&nbsp;in the array (<code>0 &lt;= i &lt; nums.length</code>), you can set&nbsp;<code>x</code>&nbsp;to any of the following:</p>



<ul class="wp-block-list"><li><code>x + nums[i]</code></li><li><code>x - nums[i]</code></li><li><code>x ^ nums[i]</code>&nbsp;(bitwise-XOR)</li></ul>



<p>Note that you can use each&nbsp;<code>nums[i]</code>&nbsp;any number of times in any order. Operations that set&nbsp;<code>x</code>&nbsp;to be out of the range&nbsp;<code>0 &lt;= x &lt;= 1000</code>&nbsp;are valid, but no more operations can be done afterward.</p>



<p>Return&nbsp;<em>the&nbsp;<strong>minimum</strong>&nbsp;number of operations needed to convert&nbsp;</em><code>x = start</code><em>&nbsp;into&nbsp;</em><code>goal</code><em>, and&nbsp;</em><code>-1</code><em>&nbsp;if it is not possible</em>.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [1,3], start = 6, goal = 4
<strong>Output:</strong> 2
<strong>Explanation:</strong>
We can go from 6 → 7 → 4 with the following 2 operations.
- 6 ^ 1 = 7
- 7 ^ 3 = 4
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [2,4,12], start = 2, goal = 12
<strong>Output:</strong> 2
<strong>Explanation:</strong>
We can go from 2 → 14 → 12 with the following 2 operations.
- 2 + 12 = 14
- 14 - 2 = 12
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [3,5,7], start = 0, goal = -4
<strong>Output:</strong> 2
<strong>Explanation:</strong>
We can go from 0 → 3 → -4 with the following 2 operations. 
- 0 + 3 = 3
- 3 - 7 = -4
Note that the last operation sets x out of the range 0 &lt;= x &lt;= 1000, which is valid.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [2,8,16], start = 0, goal = 1
<strong>Output:</strong> -1
<strong>Explanation:</strong>
There is no way to convert 0 into 1.</pre>



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



<pre class="urvanov-syntax-highlighter-plain-tag">&lt;strong&gt;Input:&lt;/strong&gt; nums = [1], start = 0, goal = 3
&lt;strong&gt;Output:&lt;/strong&gt; 3
&lt;strong&gt;Explanation:&lt;/strong&gt; 
We can go from 0 &rarr; 1 &rarr; 2 &rarr; 3 with the following 3 operations. 
- 0 + 1 = 1 
- 1 + 1 = 2
- 2 + 1 = 3</pre>



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



<ul class="wp-block-list"><li><code>1 &lt;= nums.length &lt;= 1000</code></li><li><code>-10<sup>9</sup>&nbsp;&lt;= nums[i], goal &lt;= 10<sup>9</sup></code></li><li><code>0 &lt;= start &lt;= 1000</code></li><li><code>start != goal</code></li><li>All the integers in&nbsp;<code>nums</code>&nbsp;are distinct.</li></ul>



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



<p>Time complexity: O(n*m)<br>Space complexity: O(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 minimumOperations(vector&lt;int&gt;&amp; nums, int start, int goal) {
    vector&lt;int&gt; seen(1001);
    queue&lt;int&gt; q{{start}};  
    for (int ans = 1, s = 1; !q.empty(); ++ans, s = q.size()) {
      while (s--) {
        int x = q.front(); q.pop();
        for (int n : nums)
          for (int t : {x + n, x - n, x ^ n})
            if (t == goal) 
              return ans;
            else if (t &lt; 0 || t &gt; 1000 || seen[t]++)
              continue;
            else
              q.push(t);
      }
    }
    return -1;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-2059-minimum-operations-to-convert-number/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2039. The Time When the Network Becomes Idle</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-2039-the-time-when-the-network-becomes-idle/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-2039-the-time-when-the-network-becomes-idle/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Tue, 19 Oct 2021 04:53:38 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[BFS]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[shortest path]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8623</guid>

					<description><![CDATA[There is a network of&#160;n&#160;servers, labeled from&#160;0&#160;to&#160;n - 1. You are given a 2D integer array&#160;edges, where&#160;edges[i] = [ui, vi]&#160;indicates there is a message channel&#8230;]]></description>
										<content:encoded><![CDATA[
<p>There is a network of&nbsp;<code>n</code>&nbsp;servers, labeled from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>n - 1</code>. You are given a 2D integer array&nbsp;<code>edges</code>, where&nbsp;<code>edges[i] = [u<sub>i</sub>, v<sub>i</sub>]</code>&nbsp;indicates there is a message channel between servers&nbsp;<code>u<sub>i</sub></code>&nbsp;and&nbsp;<code>v<sub>i</sub></code>, and they can pass&nbsp;<strong>any</strong>&nbsp;number of messages to&nbsp;<strong>each other</strong>&nbsp;directly in&nbsp;<strong>one</strong>&nbsp;second. You are also given a&nbsp;<strong>0-indexed</strong>&nbsp;integer array&nbsp;<code>patience</code>&nbsp;of length&nbsp;<code>n</code>.</p>



<p>All servers are&nbsp;<strong>connected</strong>, i.e., a message can be passed from one server to any other server(s) directly or indirectly through the message channels.</p>



<p>The server labeled&nbsp;<code>0</code>&nbsp;is the&nbsp;<strong>master</strong>&nbsp;server. The rest are&nbsp;<strong>data</strong>&nbsp;servers. Each data server needs to send its message to the master server for processing and wait for a reply. Messages move between servers&nbsp;<strong>optimally</strong>, so every message takes the&nbsp;<strong>least amount of time</strong>&nbsp;to arrive at the master server. The master server will process all newly arrived messages&nbsp;<strong>instantly</strong>&nbsp;and send a reply to the originating server via the&nbsp;<strong>reversed path</strong>&nbsp;the message had gone through.</p>



<p>At the beginning of second&nbsp;<code>0</code>, each data server sends its message to be processed. Starting from second&nbsp;<code>1</code>, at the&nbsp;<strong>beginning</strong>&nbsp;of&nbsp;<strong>every</strong>&nbsp;second, each data server will check if it has received a reply to the message it sent (including any newly arrived replies) from the master server:</p>



<ul class="wp-block-list"><li>If it has not, it will&nbsp;<strong>resend</strong>&nbsp;the message periodically. The data server&nbsp;<code>i</code>&nbsp;will resend the message every&nbsp;<code>patience[i]</code>&nbsp;second(s), i.e., the data server&nbsp;<code>i</code>&nbsp;will resend the message if&nbsp;<code>patience[i]</code>&nbsp;second(s) have&nbsp;<strong>elapsed</strong>&nbsp;since the&nbsp;<strong>last</strong>&nbsp;time the message was sent from this server.</li><li>Otherwise,&nbsp;<strong>no more resending</strong>&nbsp;will occur from this server.</li></ul>



<p>The network becomes&nbsp;<strong>idle</strong>&nbsp;when there are&nbsp;<strong>no</strong>&nbsp;messages passing between servers or arriving at servers.</p>



<p>Return&nbsp;<em>the&nbsp;<strong>earliest second</strong>&nbsp;starting from which the network becomes&nbsp;<strong>idle</strong></em>.</p>



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



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2021/09/22/quiet-place-example1.png" alt="example 1"/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> edges = [[0,1],[1,2]], patience = [0,2,1]
<strong>Output:</strong> 8
<strong>Explanation:</strong>
At (the beginning of) second 0,
- Data server 1 sends its message (denoted 1A) to the master server.
- Data server 2 sends its message (denoted 2A) to the master server.

At second 1,
- Message 1A arrives at the master server. Master server processes message 1A instantly and sends a reply 1A back.
- Server 1 has not received any reply. 1 second (1 &lt; patience[1] = 2) elapsed since this server has sent the message, therefore it does not resend the message.
- Server 2 has not received any reply. 1 second (1 == patience[2] = 1) elapsed since this server has sent the message, therefore it resends the message (denoted 2B).

At second 2,
- The reply 1A arrives at server 1. No more resending will occur from server 1.
- Message 2A arrives at the master server. Master server processes message 2A instantly and sends a reply 2A back.
- Server 2 resends the message (denoted 2C).
...
At second 4,
- The reply 2A arrives at server 2. No more resending will occur from server 2.
...
At second 7, reply 2D arrives at server 2.

Starting from the beginning of the second 8, there are no messages passing between servers or arriving at servers.
This is the time when the network becomes idle.
</pre>



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



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2021/09/04/network_a_quiet_place_2.png" alt="example 2"/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> edges = [[0,1],[0,2],[1,2]], patience = [0,10,10]
<strong>Output:</strong> 3
<strong>Explanation:</strong> Data servers 1 and 2 receive a reply back at the beginning of second 2.
From the beginning of the second 3, the network becomes idle.
</pre>



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



<ul class="wp-block-list"><li><code>n == patience.length</code></li><li><code>2 &lt;= n &lt;= 10<sup>5</sup></code></li><li><code>patience[0] == 0</code></li><li><code>1 &lt;= patience[i] &lt;= 10<sup>5</sup></code>&nbsp;for&nbsp;<code>1 &lt;= i &lt; n</code></li><li><code>1 &lt;= edges.length &lt;= min(10<sup>5</sup>, n * (n - 1) / 2)</code></li><li><code>edges[i].length == 2</code></li><li><code>0 &lt;= u<sub>i</sub>, v<sub>i</sub>&nbsp;&lt; n</code></li><li><code>u<sub>i</sub>&nbsp;!= v<sub>i</sub></code></li><li>There are no duplicate edges.</li><li>Each server can directly or indirectly reach another server.</li></ul>



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



<p>Compute the shortest path from node 0 to rest of the nodes using BFS.</p>



<p>Idle time for node i = (dist[i] * 2 &#8211; 1) / patince[i] * patience[i] + dist[i] * 2 + 1</p>



<p>Time complexity: O(E + V)<br>Space complexity: O(E + V)</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 networkBecomesIdle(vector&lt;vector&lt;int&gt;&gt;&amp; edges, vector&lt;int&gt;&amp; patience) {
    const int n = patience.size();
    vector&lt;vector&lt;int&gt;&gt; g(n);
    for (const auto&amp; e : edges) {
      g[e[0]].push_back(e[1]);
      g[e[1]].push_back(e[0]);
    }
    vector&lt;int&gt; ts(n, -1);
    ts[0] = 0;
    queue&lt;int&gt; q{{0}};    
    while (!q.empty()) {      
      int u = q.front(); q.pop();        
      for (int v : g[u]) {
        if (ts[v] != -1) continue;
        ts[v] = ts[u] + 1;
        q.push(v);
      }
    }
    int ans = 0;
    for (int i = 1; i &lt; n; ++i) {      
      int t = (ts[i] * 2 - 1) / patience[i] * patience[i] + ts[i] * 2 + 1;
      ans = max(ans, t);
    }    
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/graph/leetcode-2039-the-time-when-the-network-becomes-idle/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2045. Second Minimum Time to Reach Destination</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-2045-second-minimum-time-to-reach-destination/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-2045-second-minimum-time-to-reach-destination/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 18 Oct 2021 04:23:21 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[BFS]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[hard]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8613</guid>

					<description><![CDATA[A city is represented as a&#160;bi-directional connected&#160;graph with&#160;n&#160;vertices where each vertex is labeled from&#160;1&#160;to&#160;n&#160;(inclusive). The edges in the graph are represented as a 2D integer&#8230;]]></description>
										<content:encoded><![CDATA[
<p>A city is represented as a&nbsp;<strong>bi-directional connected</strong>&nbsp;graph with&nbsp;<code>n</code>&nbsp;vertices where each vertex is labeled from&nbsp;<code>1</code>&nbsp;to&nbsp;<code>n</code>&nbsp;(<strong>inclusive</strong>). The edges in the graph are represented as a 2D integer array&nbsp;<code>edges</code>, where each&nbsp;<code>edges[i] = [u<sub>i</sub>, v<sub>i</sub>]</code>&nbsp;denotes a bi-directional edge between vertex&nbsp;<code>u<sub>i</sub></code>&nbsp;and vertex&nbsp;<code>v<sub>i</sub></code>. Every vertex pair is connected by&nbsp;<strong>at most one</strong>&nbsp;edge, and no vertex has an edge to itself. The time taken to traverse any edge is&nbsp;<code>time</code>&nbsp;minutes.</p>



<p>Each vertex has a traffic signal which changes its color from&nbsp;<strong>green</strong>&nbsp;to&nbsp;<strong>red</strong>&nbsp;and vice versa every&nbsp;<code>change</code>&nbsp;minutes. All signals change&nbsp;<strong>at the same time</strong>. You can enter a vertex at&nbsp;<strong>any time</strong>, but can leave a vertex&nbsp;<strong>only when the signal is green</strong>. You&nbsp;<strong>cannot wait&nbsp;</strong>at a vertex if the signal is&nbsp;<strong>green</strong>.</p>



<p>The&nbsp;<strong>second minimum value</strong>&nbsp;is defined as the smallest value<strong>&nbsp;strictly larger&nbsp;</strong>than the minimum value.</p>



<ul class="wp-block-list"><li>For example the second minimum value of&nbsp;<code>[2, 3, 4]</code>&nbsp;is&nbsp;<code>3</code>, and the second minimum value of&nbsp;<code>[2, 2, 4]</code>&nbsp;is&nbsp;<code>4</code>.</li></ul>



<p>Given&nbsp;<code>n</code>,&nbsp;<code>edges</code>,&nbsp;<code>time</code>, and&nbsp;<code>change</code>, return&nbsp;<em>the&nbsp;<strong>second minimum time</strong>&nbsp;it will take to go from vertex&nbsp;</em><code>1</code><em>&nbsp;to vertex&nbsp;</em><code>n</code>.</p>



<p><strong>Notes:</strong></p>



<ul class="wp-block-list"><li>You can go through any vertex&nbsp;<strong>any</strong>&nbsp;number of times,&nbsp;<strong>including</strong>&nbsp;<code>1</code>&nbsp;and&nbsp;<code>n</code>.</li><li>You can assume that when the journey&nbsp;<strong>starts</strong>, all signals have just turned&nbsp;<strong>green</strong>.</li></ul>



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



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



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 5, edges = [[1,2],[1,3],[1,4],[3,4],[4,5]], time = 3, change = 5
<strong>Output:</strong> 13
<strong>Explanation:</strong>
The figure on the left shows the given graph.
The blue path in the figure on the right is the minimum time path.
The time taken is:
- Start at 1, time elapsed=0
- 1 -&gt; 4: 3 minutes, time elapsed=3
- 4 -&gt; 5: 3 minutes, time elapsed=6
Hence the minimum time needed is 6 minutes.

The red path shows the path to get the second minimum time.
- Start at 1, time elapsed=0
- 1 -&gt; 3: 3 minutes, time elapsed=3
- 3 -&gt; 4: 3 minutes, time elapsed=6
- Wait at 4 for 4 minutes, time elapsed=10
- 4 -&gt; 5: 3 minutes, time elapsed=13
Hence the second minimum time is 13 minutes.      
</pre>



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



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 2, edges = [[1,2]], time = 3, change = 2
<strong>Output:</strong> 11
<strong>Explanation:</strong>
The minimum time path is 1 -&gt; 2 with time = 3 minutes.
The second minimum time path is 1 -&gt; 2 -&gt; 1 -&gt; 2 with time = 11 minutes.</pre>



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



<ul class="wp-block-list"><li><code>2 &lt;= n &lt;= 10<sup>4</sup></code></li><li><code>n - 1 &lt;= edges.length &lt;= min(2 * 10<sup>4</sup>, n * (n - 1) / 2)</code></li><li><code>edges[i].length == 2</code></li><li><code>1 &lt;= u<sub>i</sub>, v<sub>i</sub>&nbsp;&lt;= n</code></li><li><code>u<sub>i</sub>&nbsp;!= v<sub>i</sub></code></li><li>There are no duplicate edges.</li><li>Each vertex can be reached directly or indirectly from every other vertex.</li><li><code>1 &lt;= time, change &lt;= 10<sup>3</sup></code></li></ul>



<h2 class="wp-block-heading"><strong>Solution: Best first search</strong></h2>



<p>Since we&#8217;re only looking for second best, to avoid TLE, for each vertex, keep two best time to arrival is sufficient.</p>



<p>Time complexity: O(2ElogE)<br>Space complexity: O(V+E)</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 secondMinimum(int n, vector&lt;vector&lt;int&gt;&gt;&amp; edges, int time, int change) {
    vector&lt;vector&lt;int&gt;&gt; g(n + 1);
    for (const auto&amp; e : edges) {
      g[e[0]].push_back(e[1]);
      g[e[1]].push_back(e[0]);
    }
    priority_queue&lt;pair&lt;int, int&gt;&gt; q; // {-t, node}
    q.emplace(0, 1);
    int min_time = -1;
    vector&lt;vector&lt;int&gt;&gt; ts(n + 1);
    ts[1].push_back(0);
    while (true) {
      const int t = -q.top().first;
      const int u = q.top().second;
      if (u == n) {
        if (min_time == -1 || t == min_time) { 
          min_time = t;
        } else {
          return t;
        }
      }
      q.pop();
      for (const auto&amp; v : g[u]) {
        const int tt = (((t / change) &amp; 1) ? (t + change - t % change) : t) + time;
        if ((ts[v].size() &gt; 0 &amp;&amp; tt == ts[v].back()) || ts[v].size() &gt;= 2) continue;
        ts[v].push_back(tt);        
        q.emplace(-tt, v);        
      }
    }
    return -1;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/graph/leetcode-2045-second-minimum-time-to-reach-destination/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1765. Map of Highest Peak</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-1765-map-of-highest-peak/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-1765-map-of-highest-peak/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 21 Feb 2021 05:19:36 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[BFS]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[shortest path]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8135</guid>

					<description><![CDATA[You are given an integer matrix&#160;isWater&#160;of size&#160;m x n&#160;that represents a map of&#160;land&#160;and&#160;water&#160;cells. If&#160;isWater[i][j] == 0, cell&#160;(i, j)&#160;is a&#160;land&#160;cell. If&#160;isWater[i][j] == 1, cell&#160;(i, j)&#160;is a&#160;water&#160;cell.&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You are given an integer matrix&nbsp;<code>isWater</code>&nbsp;of size&nbsp;<code>m x n</code>&nbsp;that represents a map of&nbsp;<strong>land</strong>&nbsp;and&nbsp;<strong>water</strong>&nbsp;cells.</p>



<ul class="wp-block-list"><li>If&nbsp;<code>isWater[i][j] == 0</code>, cell&nbsp;<code>(i, j)</code>&nbsp;is a&nbsp;<strong>land</strong>&nbsp;cell.</li><li>If&nbsp;<code>isWater[i][j] == 1</code>, cell&nbsp;<code>(i, j)</code>&nbsp;is a&nbsp;<strong>water</strong>&nbsp;cell.</li></ul>



<p>You must assign each cell a height in a way that follows these rules:</p>



<ul class="wp-block-list"><li>The height of each cell must be non-negative.</li><li>If the cell is a&nbsp;<strong>water</strong>&nbsp;cell, its height must be&nbsp;<code>0</code>.</li><li>Any two adjacent cells must have an absolute height difference of&nbsp;<strong>at most</strong>&nbsp;<code>1</code>. A cell is adjacent to another cell if the former is directly north, east, south, or west of the latter (i.e., their sides are touching).</li></ul>



<p>Find an assignment of heights such that the maximum height in the matrix is&nbsp;<strong>maximized</strong>.</p>



<p>Return&nbsp;<em>an integer matrix&nbsp;</em><code>height</code><em>&nbsp;of size&nbsp;</em><code>m x n</code><em>&nbsp;where&nbsp;</em><code>height[i][j]</code><em>&nbsp;is cell&nbsp;</em><code>(i, j)</code><em>&#8216;s height. If there are multiple solutions, return&nbsp;<strong>any</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/01/10/screenshot-2021-01-11-at-82045-am.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> isWater = [[0,1],[0,0]]
<strong>Output:</strong> [[1,0],[2,1]]
<strong>Explanation:</strong> The image shows the assigned heights of each cell.
The blue cell is the water cell, and the green cells are the land cells.
</pre>



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



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2021/01/10/screenshot-2021-01-11-at-82050-am.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> isWater = [[0,0,1],[1,0,0],[0,0,0]]
<strong>Output:</strong> [[1,1,0],[0,1,1],[1,2,2]]
<strong>Explanation:</strong> A height of 2 is the maximum possible height of any assignment.
Any height assignment that has a maximum height of 2 while still meeting the rules will also be accepted.
</pre>



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



<ul class="wp-block-list"><li><code>m == isWater.length</code></li><li><code>n == isWater[i].length</code></li><li><code>1 &lt;= m, n &lt;= 1000</code></li><li><code>isWater[i][j]</code>&nbsp;is&nbsp;<code>0</code>&nbsp;or&nbsp;<code>1</code>.</li><li>There is at least&nbsp;<strong>one</strong>&nbsp;water cell.</li></ul>



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



<p>h[y][x] = min distance of (x, y) to any water cell.</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:
  vector&lt;vector&lt;int&gt;&gt; highestPeak(vector&lt;vector&lt;int&gt;&gt;&amp; isWater) {
    const int m = isWater.size();
    const int n = isWater[0].size();
    vector&lt;vector&lt;int&gt;&gt; ans(m, vector&lt;int&gt;(n, INT_MIN));
    queue&lt;pair&lt;int, int&gt;&gt; q;
    for (int y = 0; y &lt; m; ++y)
      for (int x = 0; x &lt; n; ++x)
        if (isWater[y][x]) {
          q.emplace(x, y);
          ans[y][x] = 0;
        }
    const vector&lt;int&gt; dirs{0, -1, 0, 1, 0};    
    while (!q.empty()) {
      const auto [cx, cy] = q.front();
      q.pop();
      for (int i = 0; i &lt; 4; ++i) {
        const int x = cx + dirs[i];
        const int y = cy + dirs[i + 1];
        if (x &lt; 0 || x &gt;= n || y &lt; 0 || y &gt;= m) continue;
        if (ans[y][x] != INT_MIN) continue;
        ans[y][x] = ans[cy][cx] + 1;
        q.emplace(x, y);
      }      
    }
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-1765-map-of-highest-peak/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1654. Minimum Jumps to Reach Home</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-1654-minimum-jumps-to-reach-home/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-1654-minimum-jumps-to-reach-home/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 14 Nov 2020 19:46:45 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[BFS]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[steps]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7652</guid>

					<description><![CDATA[A certain bug&#8217;s home is on the x-axis at position&#160;x. Help them get there from position&#160;0. The bug jumps according to the following rules: It&#8230;]]></description>
										<content:encoded><![CDATA[
<p>A certain bug&#8217;s home is on the x-axis at position&nbsp;<code>x</code>. Help them get there from position&nbsp;<code>0</code>.</p>



<p>The bug jumps according to the following rules:</p>



<ul class="wp-block-list"><li>It can jump exactly&nbsp;<code>a</code>&nbsp;positions&nbsp;<strong>forward</strong>&nbsp;(to the right).</li><li>It can jump exactly&nbsp;<code>b</code>&nbsp;positions&nbsp;<strong>backward</strong>&nbsp;(to the left).</li><li>It cannot jump backward twice in a row.</li><li>It cannot jump to any&nbsp;<code>forbidden</code>&nbsp;positions.</li></ul>



<p>The bug may jump forward&nbsp;<strong>beyond</strong>&nbsp;its home, but it&nbsp;<strong>cannot jump</strong>&nbsp;to positions numbered with&nbsp;<strong>negative</strong>&nbsp;integers.</p>



<p>Given an array of integers&nbsp;<code>forbidden</code>, where&nbsp;<code>forbidden[i]</code>&nbsp;means that the bug cannot jump to the position&nbsp;<code>forbidden[i]</code>, and integers&nbsp;<code>a</code>,&nbsp;<code>b</code>, and&nbsp;<code>x</code>, return&nbsp;<em>the minimum number of jumps needed for the bug to reach its home</em>. If there is no possible sequence of jumps that lands the bug on position&nbsp;<code>x</code>, return&nbsp;<code>-1.</code></p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> forbidden = [14,4,18,1,15], a = 3, b = 15, x = 9
<strong>Output:</strong> 3
<strong>Explanation:</strong> 3 jumps forward (0 -&gt; 3 -&gt; 6 -&gt; 9) will get the bug home.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> forbidden = [8,3,16,6,12,20], a = 15, b = 13, x = 11
<strong>Output:</strong> -1
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> forbidden = [1,6,2,14,5,17,4], a = 16, b = 9, x = 7
<strong>Output:</strong> 2
<strong>Explanation:</strong> One jump forward (0 -&gt; 16) then one jump backward (16 -&gt; 7) will get the bug home.
</pre>



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



<ul class="wp-block-list"><li><code>1 &lt;= forbidden.length &lt;= 1000</code></li><li><code>1 &lt;= a, b, forbidden[i] &lt;= 2000</code></li><li><code>0 &lt;= x &lt;= 2000</code></li><li>All the elements in&nbsp;<code>forbidden</code>&nbsp;are distinct.</li><li>Position&nbsp;<code>x</code>&nbsp;is not forbidden.</li></ul>



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



<p>Normal BFS with two tricks:<br>1. For each position, we need to track whether it&#8217;s reached via a forward jump or backward jump<br>2. How far should we go? If we don&#8217;t limit, it can go forever which leads to TLE/MLE. We can limit the distance to 2*max_jump, e.g. 4000, that&#8217;s maximum distance we can jump back to home in one shot.</p>



<p>Time complexity: O(max_distance * 2)<br>Space complexity: O(max_distance * 2)</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 minimumJumps(vector&lt;int&gt;&amp; forbidden, int a, int b, int x) {
    constexpr int kMaxPosition = 4000;
    if (x == 0) return 0;
    queue&lt;pair&lt;int, bool&gt;&gt; q{{{0, true}}};
    unordered_set&lt;int&gt; seen1, seen2;
    for (int f : forbidden) seen1.insert(f), seen2.insert(f);
    seen1.insert(0);
    int steps = 0;
    while (!q.empty()) {      
      int size = q.size();
      while (size--) {
        auto [cur, forward] = q.front(); q.pop();        
        if (cur == x) return steps;
        if (cur &gt; kMaxPosition) continue; // no way to go back
        if (seen1.insert(cur + a).second)      
          q.emplace(cur + a, true);
        if (cur - b &gt;= 0 &amp;&amp; forward &amp;&amp; seen2.insert(cur - b).second)
          q.emplace(cur - b, false);
      }
      ++steps;
    }
    return -1;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-1654-minimum-jumps-to-reach-home/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1631. Path With Minimum Effort</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-1631-path-with-minimum-effort/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-1631-path-with-minimum-effort/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 25 Oct 2020 06:26:42 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[BFS]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[medium]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7557</guid>

					<description><![CDATA[You are a hiker preparing for an upcoming hike. You are given&#160;heights, a 2D array of size&#160;rows x columns, where&#160;heights[row][col]&#160;represents the height of cell&#160;(row, col).&#8230;]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-4-3 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="花花酱 LeetCode 1631. Path With Minimum Effort - 刷题找工作 EP364" width="500" height="281" src="https://www.youtube.com/embed/bfDOyz0DnQ8?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 a hiker preparing for an upcoming hike. You are given&nbsp;<code>heights</code>, a 2D array of size&nbsp;<code>rows x columns</code>, where&nbsp;<code>heights[row][col]</code>&nbsp;represents the height of cell&nbsp;<code>(row, col)</code>. You are situated in the top-left cell,&nbsp;<code>(0, 0)</code>, and you hope to travel to the bottom-right cell,&nbsp;<code>(rows-1, columns-1)</code>&nbsp;(i.e.,&nbsp;<strong>0-indexed</strong>). You can move&nbsp;<strong>up</strong>,&nbsp;<strong>down</strong>,&nbsp;<strong>left</strong>, or&nbsp;<strong>right</strong>, and you wish to find a route that requires the minimum&nbsp;<strong>effort</strong>.</p>



<p>A route&#8217;s&nbsp;<strong>effort</strong>&nbsp;is the&nbsp;<strong>maximum absolute difference</strong>in heights between two consecutive cells of the route.</p>



<p>Return&nbsp;<em>the minimum&nbsp;<strong>effort</strong>&nbsp;required to travel from the top-left cell to the bottom-right cell.</em></p>



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



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> heights = [[1,2,2],[3,8,2],[5,3,5]]
<strong>Output:</strong> 2
<strong>Explanation:</strong> The route of [1,3,5,3,5] has a maximum absolute difference of 2 in consecutive cells.
This is better than the route of [1,2,2,2,5], where the maximum absolute difference is 3.
</pre>



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



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> heights = [[1,2,3],[3,8,4],[5,3,5]]
<strong>Output:</strong> 1
<strong>Explanation:</strong> The route of [1,2,3,4,5] has a maximum absolute difference of 1 in consecutive cells, which is better than route [1,3,5,3,5].
</pre>



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



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> heights = [[1,2,1,1,1],[1,2,1,2,1],[1,2,1,2,1],[1,2,1,2,1],[1,1,1,2,1]]
<strong>Output:</strong> 0
<strong>Explanation:</strong> This route does not require any effort.
</pre>



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



<ul class="wp-block-list"><li><code>rows == heights.length</code></li><li><code>columns == heights[i].length</code></li><li><code>1 &lt;= rows, columns &lt;= 100</code></li><li><code>1 &lt;= heights[i][j] &lt;= 10<sup>6</sup></code></li></ul>



<h2 class="wp-block-heading"><strong>Solution: &#8220;Lazy BFS / DP&#8221;</strong></h2>



<figure class="wp-block-image size-large"><img decoding="async" width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/10/1631-ep364-1.png" alt="" class="wp-image-7562" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/10/1631-ep364-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/10/1631-ep364-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/10/1631-ep364-1-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/10/1631-ep364-2.png" alt="" class="wp-image-7563" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/10/1631-ep364-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/10/1631-ep364-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/10/1631-ep364-2-768x432.png 768w" sizes="auto, (max-width: 960px) 100vw, 960px" /></figure>



<p>dp[y][x] = min(max(dp[ty][tx], abs(h[ty][tx] &#8211; h[y][x]))) (x, y) and (tx, ty) are neighbors<br>repeat this process for at most rows * cols times.<br>if dp does not change after one round which means we found the optimal solution and can break earlier.</p>



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua, 824 ms
class Solution {
public:
  int minimumEffortPath(vector&lt;vector&lt;int&gt;&gt;&amp; heights) {
    const int r = heights.size();
    const int c = heights[0].size();
    int dp[100][100];
    memset(dp, 0x7f, sizeof(dp));
    dp[0][0] = 0;
    vector&lt;int&gt; dirs{0, -1, 0, 1, 0};
    for (int k = 0; k &lt; r * c; ++k) {
      bool stable = true;
      for (int y = 0; y &lt; r; ++y)
        for (int x = 0; x &lt; c; ++x)
          for (int d = 0; d &lt; 4; ++d) {
            int tx = x + dirs[d];
            int ty = y + dirs[d + 1];
            if (tx &lt; 0 || tx == c || ty &lt; 0 || ty == r) continue;
            int t = max(dp[ty][tx], abs(heights[ty][tx] - heights[y][x]));
            if (t &lt; dp[y][x]) {
              stable = false;
              dp[y][x] = t;
            }
          }    
      if (stable) break;
    }
    return dp[r - 1][c - 1];
  }
};</pre>
</div></div>



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



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



<p>Use binary search to guess a cost and then check whether there is path that is under the cost.</p>



<p>Time complexity: O(mn*log(max(h) &#8211; min(h)))<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, 620 ms
class Solution {
public:
  int minimumEffortPath(vector&lt;vector&lt;int&gt;&gt;&amp; heights) {
    const int rows = heights.size();
    const int cols = heights[0].size();    
    vector&lt;int&gt; dirs{0, -1, 0, 1, 0};
    auto bfs = [&amp;](int cost) -&gt; bool {
      queue&lt;pair&lt;int, int&gt;&gt; q;
      vector&lt;int&gt; seen(cols * rows);
      q.emplace(0, 0);
      seen[0] = 1;
      while (!q.empty()) {
        auto [cx, cy] = q.front(); q.pop();
        if (cx == cols - 1 &amp;&amp; cy == rows - 1) return true;
        for (int i = 0; i &lt; 4; ++i) {
          int x = cx + dirs[i];
          int y = cy + dirs[i + 1];
          if (x &lt; 0 || x == cols || y &lt; 0 || y == rows) continue;
          if (abs(heights[cy][cx] - heights[y][x]) &gt; cost) continue;
          if (seen[y * cols + x]++) continue;
          q.emplace(x, y);
        }          
      }
      return false;
    };
    int l = 0, r = 1e6 + 1;
    while (l &lt; r) {
      const int m = l + (r - l) / 2;
      if (bfs(m)) {
        r = m;
      } else {
        l = m + 1;
      }
    }
    return l;
  }
};</pre>
</div></div>



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



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/10/1631-ep364-4.png" alt="" class="wp-image-7565" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/10/1631-ep364-4.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/10/1631-ep364-4-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/10/1631-ep364-4-768x432.png 768w" sizes="auto, (max-width: 960px) 100vw, 960px" /></figure>



<p>Time complexity: O(mnlog(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, 216 ms
class Solution {
public:
  int minimumEffortPath(vector&lt;vector&lt;int&gt;&gt;&amp; heights) {
    const vector&lt;int&gt; dirs{0, -1, 0, 1, 0}; 
    const int rows = heights.size();
    const int cols = heights[0].size();
    using Node = pair&lt;int, int&gt;;
    priority_queue&lt;Node, vector&lt;Node&gt;, greater&lt;Node&gt;&gt; q;
    vector&lt;int&gt; dist(rows * cols, INT_MAX / 2);    
    q.emplace(0, 0);
    dist[0] = 0;
    while (!q.empty()) {
      auto [t, u] = q.top(); q.pop();
      if (u == rows * cols - 1) return t;
      if (t &gt; dist[u]) continue;
      const int ux = u % cols;
      const int uy = u / cols;
      for (int i = 0; i &lt; 4; ++i) {
        const int x = ux + dirs[i];
        const int y = uy + dirs[i + 1];
        if (x &lt; 0 || x == cols || y &lt; 0 || y == rows) continue;
        const int v = y * cols + x;
        const int c = abs(heights[uy][ux] - heights[y][x]);
        if (max(t, c) &gt;= dist[v]) continue;
        q.emplace(dist[v] = max(t, c), v);
      }
    }
    return -1;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/graph/leetcode-1631-path-with-minimum-effort/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1466. Reorder Routes to Make All Paths Lead to the City Zero</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-1466-reorder-routes-to-make-all-paths-lead-to-the-city-zero/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-1466-reorder-routes-to-make-all-paths-lead-to-the-city-zero/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 31 May 2020 17:41:30 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[BFS]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[medium]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=6860</guid>

					<description><![CDATA[There are&#160;n&#160;cities numbered from&#160;0&#160;to&#160;n-1&#160;and&#160;n-1&#160;roads such that&#160;there is only one way to travel between two&#160;different cities (this network form a tree).&#160;Last year,&#160;The ministry of transport&#160;decided to&#8230;]]></description>
										<content:encoded><![CDATA[
<p>There are&nbsp;<code>n</code>&nbsp;cities numbered from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>n-1</code>&nbsp;and&nbsp;<code>n-1</code>&nbsp;roads such that&nbsp;there is only one way to travel between two&nbsp;different cities (this network form a tree).&nbsp;Last year,&nbsp;The ministry of transport&nbsp;decided to orient the roads in one direction because they are too narrow.</p>



<p>Roads are represented by&nbsp;<code>connections</code>&nbsp;where&nbsp;<code>connections[i] = [a, b]</code>&nbsp;represents a&nbsp;road&nbsp;from city&nbsp;<code>a</code>&nbsp;to&nbsp;<code>b</code>.</p>



<p>This year, there will be a big event in the capital (city 0), and many people want to travel to this city.</p>



<p>Your task consists of reorienting&nbsp;some roads such that each city can visit the city&nbsp;0. Return the&nbsp;<strong>minimum</strong>&nbsp;number of edges changed.</p>



<p>It&#8217;s&nbsp;<strong>guaranteed</strong>&nbsp;that each city can reach the city 0 after reorder.</p>



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



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 6, connections = [[0,1],[1,3],[2,3],[4,0],[4,5]]
<strong>Output:</strong> 3
<strong>Explanation: </strong>Change the direction of edges show in red such that each node can reach the node 0 (capital).</pre>



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



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 5, connections = [[1,0],[1,2],[3,2],[3,4]]
<strong>Output:</strong> 2
<strong>Explanation: </strong>Change the direction of edges show in red such that each node can reach the node 0 (capital).</pre>



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



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



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



<ul class="wp-block-list"><li><code>2 &lt;= n &lt;= 5 * 10^4</code></li><li><code>connections.length == n-1</code></li><li><code>connections[i].length == 2</code></li><li><code>0 &lt;= connections[i][0], connections[i][1] &lt;= n-1</code></li><li><code>connections[i][0] != connections[i][1]</code></li></ul>



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



<p>Augment the graph<br>g[u][v] = 1, g[v][u] = 0,  u->v is an edge in the original graph.</p>



<p>BFS from 0, sum up all the edge costs to visit all the nodes.</p>



<p>Time complexity: O(n)<br>Space complexity: O(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 minReorder(int n, vector&lt;vector&lt;int&gt;&gt;&amp; connections) {
    vector&lt;vector&lt;pair&lt;int, int&gt;&gt;&gt; g(n); // u -&gt; {v, cost}
    for (const auto&amp; e : connections) {
      g[e[0]].emplace_back(e[1], 1); // u -&gt; v, needs flip
      g[e[1]].emplace_back(e[0], 0); // v -&gt; u, no cost
    }
    int ans = 0;
    queue&lt;int&gt; q{{0}};
    vector&lt;int&gt; seen(n);
    while (!q.empty()) {
      int cur = q.front(); q.pop();
      seen[cur] = 1;
      for (const auto&amp; [nxt, cost] : g[cur]) {
        if (seen[nxt]) continue;
        ans += cost;
        q.push(nxt);
      }
    }
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/graph/leetcode-1466-reorder-routes-to-make-all-paths-lead-to-the-city-zero/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 1377. Frog Position After T Seconds</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-1377-frog-position-after-t-seconds/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-1377-frog-position-after-t-seconds/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 08 Mar 2020 19:49:39 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[BFS]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[probability]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=6423</guid>

					<description><![CDATA[Given an undirected tree&#160;consisting of&#160;n&#160;vertices numbered from 1 to&#160;n. A frog starts jumping&#160;from the&#160;vertex 1. In one second, the frog&#160;jumps from its&#160;current&#160;vertex to another&#160;unvisited&#160;vertex if&#8230;]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-4-3 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="花花酱 LeetCode 1377. Frog Position After T Seconds - 刷题找工作 EP313" width="500" height="375" src="https://www.youtube.com/embed/B5nDIxkoEyo?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>Given an undirected tree&nbsp;consisting of&nbsp;<code>n</code>&nbsp;vertices numbered from 1 to&nbsp;<code>n</code>. A frog starts jumping&nbsp;from the&nbsp;<strong>vertex 1</strong>. In one second, the frog&nbsp;jumps from its&nbsp;current&nbsp;vertex to another&nbsp;<strong>unvisited</strong>&nbsp;vertex if they are directly connected. The frog can not jump back to a visited vertex.&nbsp;In case the frog can jump to several vertices it jumps randomly to one of them with the same probability, otherwise, when the frog can not jump to any unvisited vertex it jumps forever on the same vertex.&nbsp;</p>



<p>The edges of the undirected tree&nbsp;are given in the array&nbsp;<code>edges</code>, where&nbsp;<code>edges[i] = [from<sub>i</sub>, to<sub>i</sub>]</code>&nbsp;means that exists an edge connecting directly the vertices&nbsp;<code>from<sub>i</sub></code>&nbsp;and&nbsp;<code>to<sub>i</sub></code>.</p>



<p><em>Return the probability that after&nbsp;<code>t</code>&nbsp;seconds the frog is on the vertex&nbsp;<code>target</code>.</em></p>



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



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 7, edges = [[1,2],[1,3],[1,7],[2,4],[2,6],[3,5]], t = 2, target = 4
<strong>Output:</strong> 0.16666666666666666 
<strong>Explanation: </strong>The figure above shows the given graph. The frog starts at vertex 1, jumping with 1/3 probability to the vertex 2 after <strong>second 1</strong> and then jumping with 1/2 probability to vertex 4 after <strong>second 2</strong>. Thus the probability for the frog is on the vertex 4 after 2 seconds is 1/3 * 1/2 = 1/6 = 0.16666666666666666. 
</pre>



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



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 7, edges = [[1,2],[1,3],[1,7],[2,4],[2,6],[3,5]], t = 1, target = 7
<strong>Output:</strong> 0.3333333333333333
<strong>Explanation: </strong>The figure above shows the given graph. The frog starts at vertex 1, jumping with 1/3 = 0.3333333333333333 probability to the vertex 7 after <strong>second 1</strong>. 
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 7, edges = [[1,2],[1,3],[1,7],[2,4],[2,6],[3,5]], t = 20, target = 6
<strong>Output:</strong> 0.16666666666666666
</pre>



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



<ul class="wp-block-list"><li><code>1 &lt;= n &lt;= 100</code></li><li><code>edges.length == n-1</code></li><li><code>edges[i].length == 2</code></li><li><code>1 &lt;= edges[i][0], edges[i][1] &lt;= n</code></li><li><code>1 &lt;= t&nbsp;&lt;= 50</code></li><li><code>1 &lt;= target&nbsp;&lt;= n</code></li><li>Answers within&nbsp;<code>10^-5</code>&nbsp;of the actual value will be accepted as correct.</li></ul>



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



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/03/1373-ep313.png" alt="" class="wp-image-6463" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/03/1373-ep313.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/03/1373-ep313-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/03/1373-ep313-768x432.png 768w" sizes="auto, (max-width: 960px) 100vw, 960px" /></figure>



<p>key: if a node has children, the fog jumps to to children so the probability at current node will become 0.</p>



<p>Time complexity: O(n)<br>Space complexity: O(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:
  double frogPosition(int n, vector&lt;vector&lt;int&gt;&gt;&amp; edges, int t, int target) {
    vector&lt;double&gt; p(n + 1);
    p[1] = 1.0;
    vector&lt;vector&lt;int&gt;&gt; g(n + 1);
    for (const auto&amp; e : edges) {
      g[e[0]].push_back(e[1]);
      g[e[1]].push_back(e[0]);
    }
    vector&lt;int&gt; seen(n + 1);
    seen[1] = 1;
    queue&lt;int&gt; q{{1}};
    while (t--) {
      int size = q.size();      
      while (size--) {
        int cur = q.front(); q.pop();
        int children = 0;
        for (int nxt : g[cur])
          if (!seen[nxt]) ++children;
        for (int nxt : g[cur])
          if (!seen[nxt]++) {
            q.push(nxt);
            p[nxt] += p[cur] / children;
          }
        // key: fog jumps this node has children
        if (children &gt; 0) p[cur] = 0.0;
      }
    }
    return p[target];
  }
};</pre>
</div></div>



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

<pre class="urvanov-syntax-highlighter-plain-tag">class Solution:
  def frogPosition(self, n: int, edges: List[List[int]],
                   t: int, target: int) -&amp;gt; float:
    p = [0] + [1] + [0] * (n - 1)
    seen = [False] + [True] + [False] * (n - 1)    
    q = [1]
    g = [[] for _ in range(n + 1)]
    for i, j in edges:
      g[i].append(j)
      g[j].append(i)
    for _ in range(t):
      q2 = []
      for cur in q:
        children = sum([not seen[nxt] for nxt in g[cur]])
        for nxt in g[cur]:
          if seen[nxt]: continue
          seen[nxt] = True
          q2.append(nxt)
          p[nxt] = p[cur] / children
        if children &amp;gt; 0: p[cur] = 0
      q = q2
    return p[target]</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-1377-frog-position-after-t-seconds/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1368. Minimum Cost to Make at Least One Valid Path in a Grid</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-1368-minimum-cost-to-make-at-least-one-valid-path-in-a-grid/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-1368-minimum-cost-to-make-at-least-one-valid-path-in-a-grid/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 01 Mar 2020 07:06:28 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[BFS]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[O(mn)]]></category>
		<category><![CDATA[search]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=6384</guid>

					<description><![CDATA[Given a&#160;m&#160;x&#160;ngrid. Each cell of the&#160;grid&#160;has a sign pointing to the next cell you should visit if you are currently in this cell. The sign&#8230;]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="花花酱 LeetCode 1368. Minimum Cost to Make at Least One Valid Path in a Grid - 刷题找工作 EP310" width="500" height="281" src="https://www.youtube.com/embed/ox8Z8maR6R8?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>Given a&nbsp;<em>m</em>&nbsp;x&nbsp;<em>n</em><code>grid</code>. Each cell of the&nbsp;<code>grid</code>&nbsp;has a sign pointing to the next cell you should visit if you are currently in this cell. The sign of&nbsp;<code>grid[i][j]</code>&nbsp;can be:</p>



<ul class="wp-block-list"><li><strong>1</strong>&nbsp;which means go to the cell to the right. (i.e go from&nbsp;<code>grid[i][j]</code>&nbsp;to&nbsp;<code>grid[i][j + 1]</code>)</li><li><strong>2</strong>&nbsp;which means go to the cell to the left. (i.e go from&nbsp;<code>grid[i][j]</code>&nbsp;to&nbsp;<code>grid[i][j - 1]</code>)</li><li><strong>3</strong>&nbsp;which means go to the lower cell. (i.e go from&nbsp;<code>grid[i][j]</code>&nbsp;to&nbsp;<code>grid[i + 1][j]</code>)</li><li><strong>4</strong>&nbsp;which means go to the upper cell. (i.e go from&nbsp;<code>grid[i][j]</code>&nbsp;to&nbsp;<code>grid[i - 1][j]</code>)</li></ul>



<p>Notice&nbsp;that there could be some&nbsp;<strong>invalid signs</strong>&nbsp;on the cells of the&nbsp;<code>grid</code>&nbsp;which points outside the&nbsp;<code>grid</code>.</p>



<p>You will initially start at the 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;following the signs on the grid. The valid path&nbsp;<strong>doesn&#8217;t have to be the shortest</strong>.</p>



<p>You can modify the sign on a cell with&nbsp;<code>cost = 1</code>. You can modify the sign on a cell&nbsp;<strong>one time only</strong>.</p>



<p>Return&nbsp;<em>the minimum cost</em>&nbsp;to make the grid have at least one valid path.</p>



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



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> grid = [[1,1,1,1],[2,2,2,2],[1,1,1,1],[2,2,2,2]]
<strong>Output:</strong> 3
<strong>Explanation:</strong> You will start at point (0, 0).
The path to (3, 3) is as follows. (0, 0) --&gt; (0, 1) --&gt; (0, 2) --&gt; (0, 3) change the arrow to down with cost = 1 --&gt; (1, 3) --&gt; (1, 2) --&gt; (1, 1) --&gt; (1, 0) change the arrow to down with cost = 1 --&gt; (2, 0) --&gt; (2, 1) --&gt; (2, 2) --&gt; (2, 3) change the arrow to down with cost = 1 --&gt; (3, 3)
The total cost = 3.
</pre>



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



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> grid = [[1,1,3],[3,2,2],[1,1,4]]
<strong>Output:</strong> 0
<strong>Explanation:</strong> You can follow the path from (0, 0) to (2, 2).
</pre>



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



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



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



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



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



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> grid = [[4]]
<strong>Output:</strong> 0
</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;= 100</code></li></ul>



<h2 class="wp-block-heading"><strong>Solution 1: Lazy BFS (fake DP)</strong></h2>



<p>dp[i][j] := min steps to reach (i, j)</p>



<p>Time complexity: O((m+n)*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 minCost(vector&lt;vector&lt;int&gt;&gt;&amp; grid) {
    int m = grid.size();
    int n = grid[0].size();
    vector&lt;vector&lt;int&gt;&gt; dp(m, vector&lt;int&gt;(n, INT_MAX / 2));    
        
    dp[0][0] = 0;
    auto solve = [&amp;](int x, int y) {
      int&amp; v = dp[y][x];
      if (x &gt; 0) v = min(v, dp[y][x - 1] + (grid[y][x - 1] != 1));
      if (y &gt; 0) v = min(v, dp[y - 1][x] + (grid[y - 1][x] != 3));
      if (x &lt; n - 1) v = min(v, dp[y][x + 1] + (grid[y][x + 1] != 2));
      if (y &lt; m - 1) v = min(v, dp[y + 1][x] + (grid[y + 1][x] != 4));
    };
    
    // At most m + n steps to propagate the results to (m - 1, n -1).
    for (int k = 0; k &lt;= (m + n); ++k) {
      for (int y = 0; y &lt; m; ++y)
        for (int x = 0; x &lt; n; ++x)
          solve(x, y);
      for (int y = m - 1; y &gt;= 0; --y)
        for (int x = n - 1; x &gt;= 0; --x)
          solve(x, y);
    }
    return dp[m - 1][n - 1];
  }
};</pre>
</div></div>



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua, 88 ms / 22.9 MB
class Solution {
public:
  int minCost(vector&lt;vector&lt;int&gt;&gt;&amp; grid) {
    const int m = grid.size();
    const int n = grid[0].size();
    vector&lt;vector&lt;int&gt;&gt; dp(m, vector&lt;int&gt;(n, INT_MAX / 2));
    dp[0][0] = 0;
    while (true) {
      auto prev(dp);
      for (int i = 0; i &lt; m; ++i)
        for (int j = 0; j &lt; n; ++j) {
          if (i &gt; 0) dp[i][j] = min(dp[i][j], dp[i - 1][j] + (grid[i - 1][j] != 3));
          if (j &gt; 0) dp[i][j] = min(dp[i][j], dp[i][j - 1] + (grid[i][j - 1] != 1));
        }            
      for (int i = m - 1; i &gt;= 0; --i)
        for (int j = n - 1; j &gt;= 0; --j) {
          if (i != m - 1) dp[i][j] = min(dp[i][j], dp[i + 1][j] + (grid[i + 1][j] != 4));
          if (j != n - 1) dp[i][j] = min(dp[i][j], dp[i][j + 1] + (grid[i][j + 1] != 2));
        }
      if (prev == dp) break; // optimal solution obtained.
    }
    return dp[m - 1][n - 1];
  }
};</pre>
</div></div>



<h2 class="wp-block-heading"><strong>Solution 2: 0-1 BFS</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:
  int minCost(vector&lt;vector&lt;int&gt;&gt;&amp; grid) {
    const int m = grid.size();
    const int n = grid[0].size();
    deque&lt;pair&lt;int, int&gt;&gt; q{{0, 0}};
    vector&lt;char&gt; seen(m * n);
    vector&lt;vector&lt;int&gt;&gt; dirs{{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    while (!q.empty()) {
      auto [p, cost] = q.front(); q.pop_front();
      int x = p % n, y = p / n;
      if (x == n - 1 &amp;&amp; y == m - 1) return cost;
      if (seen[p]++) continue;
      for (int i = 0; i &lt; 4; ++i) {
        int tx = x + dirs[i][0], ty = y + dirs[i][1];
        int tp = ty * n + tx;
        if (tx &lt; 0 || ty &lt; 0 || tx &gt;= n || ty &gt;= m || seen[tp]) continue;
        if (grid[y][x] == i + 1)
          q.emplace_front(tp, cost);
        else
          q.emplace_back(tp, cost + 1);
      }
    }    
    return -1;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-1368-minimum-cost-to-make-at-least-one-valid-path-in-a-grid/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1345. Jump Game IV</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-1345-jump-game-iv/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-1345-jump-game-iv/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 08 Feb 2020 17:29:47 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[BFS]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[hashtable]]></category>
		<category><![CDATA[jump game]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=6269</guid>

					<description><![CDATA[Given an array of&#160;integers&#160;arr, you are initially positioned at the first index of the array. In one step you can jump from index&#160;i&#160;to index: i&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Given an array of&nbsp;integers&nbsp;<code>arr</code>, you are initially positioned at the first index of the array.</p>



<p>In one step you can jump from index&nbsp;<code>i</code>&nbsp;to index:</p>



<ul class="wp-block-list"><li><code>i + 1</code>&nbsp;where:&nbsp;<code>i + 1 &lt; arr.length</code>.</li><li><code>i - 1</code>&nbsp;where:&nbsp;<code>i - 1 &gt;= 0</code>.</li><li><code>j</code>&nbsp;where:&nbsp;<code>arr[i] == arr[j]</code>&nbsp;and&nbsp;<code>i != j</code>.</li></ul>



<p>Return&nbsp;<em>the minimum number of steps</em>&nbsp;to reach the&nbsp;<strong>last index</strong>&nbsp;of the array.</p>



<p>Notice that you can not jump outside of the array at any time.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> arr = [100,-23,-23,404,100,23,23,23,3,404]
<strong>Output:</strong> 3
<strong>Explanation:</strong> You need three jumps from index 0 --&gt; 4 --&gt; 3 --&gt; 9. Note that index 9 is the last index of the array.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> arr = [7]
<strong>Output:</strong> 0
<strong>Explanation:</strong> Start index is the last index. You don't need to jump.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> arr = [7,6,9,6,9,6,9,7]
<strong>Output:</strong> 1
<strong>Explanation:</strong> You can jump directly from index 0 to index 7 which is last index of the array.
</pre>



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



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



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> arr = [11,22,7,7,7,7,7,7,7,22,13]
<strong>Output:</strong> 3
</pre>



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



<ul class="wp-block-list"><li><code>1 &lt;= arr.length &lt;= 5 * 10^4</code></li><li><code>-10^8 &lt;= arr[i] &lt;= 10^8</code></li></ul>



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



<p>Use a hashtable to store the indices of each unique number.</p>



<p>each index i has neighbors (i-1, i + 1, hashtable[arr[i]])</p>



<p>Use BFS to find the shortest path in this unweighted graph.</p>



<p>Key optimization, clear hashtable[arr[i]] after the first use, since all nodes are already on queue, no longer needed.</p>



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua, 124 ms, 30.5 MB
class Solution {
public:
  int minJumps(vector&lt;int&gt;&amp; arr) {
    const int n = arr.size();
    unordered_map&lt;int, vector&lt;int&gt;&gt; m;
    for (int i = 0; i &lt; n; ++i)
      m[arr[i]].push_back(i);
    vector&lt;int&gt; seen(n);
    queue&lt;int&gt; q({0});    
    seen[0] = 1;
    int steps = 0;
    while (!q.empty()) {
      int size = q.size();
      while (size--) {
        int i = q.front(); q.pop();        
        if (i == n - 1) return steps;
        if (i - 1 &gt;= 0 &amp;&amp; !seen[i - 1]++) q.push(i - 1);
        if (i + 1 &lt; n &amp;&amp; !seen[i + 1]++) q.push(i + 1);
        auto it = m.find(arr[i]);
        if (it == m.end()) continue;
        for (int nxt : it-&gt;second)
          if (!seen[nxt]++) q.push(nxt);
        m.erase(it); // no longer needed.
      }
      ++steps;
    }
    return -1;
  }
};</pre>
</div></div>



<h2 class="wp-block-heading"><strong>Related Problems</strong></h2>



<ul class="wp-block-list"><li><a href="https://zxi.mytechroad.com/blog/greedy/leetcode-55-jump-game/">https://zxi.mytechroad.com/blog/greedy/leetcode-55-jump-game/</a></li><li><a href="https://zxi.mytechroad.com/blog/greedy/leetcode-45-jump-game-ii/">https://zxi.mytechroad.com/blog/greedy/leetcode-45-jump-game-ii/</a></li><li><a href="https://zxi.mytechroad.com/blog/searching/leetcode-1306-jump-game-iii/">https://zxi.mytechroad.com/blog/searching/leetcode-1306-jump-game-iii/</a></li><li><a href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1344-jump-game-v/">https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1344-jump-game-v/</a></li></ul>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-1345-jump-game-iv/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
