<?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>O(mn) Archives - Huahua&#039;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/tag/omn/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog/tag/omn/</link>
	<description></description>
	<lastBuildDate>Sat, 31 Oct 2020 22:11:22 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.0.8</generator>

<image>
	<url>https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/cropped-photo-32x32.jpg</url>
	<title>O(mn) Archives - Huahua&#039;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog/tag/omn/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>花花酱 LeetCode 1639. Number of Ways to Form a Target String Given a Dictionary</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1639-number-of-ways-to-form-a-target-string-given-a-dictionary/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1639-number-of-ways-to-form-a-target-string-given-a-dictionary/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 31 Oct 2020 22:10:07 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[O(mn)]]></category>
		<category><![CDATA[string]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7589</guid>

					<description><![CDATA[<p>You are given a list of strings of the&#160;same length&#160;words&#160;and a string&#160;target. Your task is to form&#160;target&#160;using the given&#160;words&#160;under the following rules: target&#160;should be formed&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1639-number-of-ways-to-form-a-target-string-given-a-dictionary/">花花酱 LeetCode 1639. Number of Ways to Form a Target String Given a Dictionary</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>You are given a list of strings of the&nbsp;<strong>same length</strong>&nbsp;<code>words</code>&nbsp;and a string&nbsp;<code>target</code>.</p>



<p>Your task is to form&nbsp;<code>target</code>&nbsp;using the given&nbsp;<code>words</code>&nbsp;under the following rules:</p>



<ul><li><code>target</code>&nbsp;should be formed from left to right.</li><li>To form the&nbsp;<code>i<sup>th</sup></code>&nbsp;character (<strong>0-indexed</strong>) of&nbsp;<code>target</code>, you can choose the&nbsp;<code>k<sup>th</sup></code>&nbsp;character of the&nbsp;<code>j<sup>th</sup></code>&nbsp;string in&nbsp;<code>words</code>&nbsp;if&nbsp;<code>target[i] = words[j][k]</code>.</li><li>Once you use the&nbsp;<code>k<sup>th</sup></code>&nbsp;character of the&nbsp;<code>j<sup>th</sup></code>&nbsp;string of&nbsp;<code>words</code>, you&nbsp;<strong>can no longer</strong>&nbsp;use the&nbsp;<code>x<sup>th</sup></code>&nbsp;character of any string in&nbsp;<code>words</code>&nbsp;where&nbsp;<code>x &lt;= k</code>. In other words, all characters to the left of or at index&nbsp;<code>k</code>&nbsp;become unusuable for every string.</li><li>Repeat the process until you form the string&nbsp;<code>target</code>.</li></ul>



<p><strong>Notice</strong>&nbsp;that you can use&nbsp;<strong>multiple characters</strong>&nbsp;from the&nbsp;<strong>same string</strong>&nbsp;in&nbsp;<code>words</code>&nbsp;provided the conditions above are met.</p>



<p>Return&nbsp;<em>the number of ways to form&nbsp;<code>target</code>&nbsp;from&nbsp;<code>words</code></em>. Since the answer may be too large, return it&nbsp;<strong>modulo</strong>&nbsp;<code>10<sup>9</sup>&nbsp;+ 7</code>.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> words = ["acca","bbbb","caca"], target = "aba"
<strong>Output:</strong> 6
<strong>Explanation:</strong> There are 6 ways to form target.
"aba" -&gt; index 0 ("acca"), index 1 ("bbbb"), index 3 ("caca")
"aba" -&gt; index 0 ("acca"), index 2 ("bbbb"), index 3 ("caca")
"aba" -&gt; index 0 ("acca"), index 1 ("bbbb"), index 3 ("acca")
"aba" -&gt; index 0 ("acca"), index 2 ("bbbb"), index 3 ("acca")
"aba" -&gt; index 1 ("caca"), index 2 ("bbbb"), index 3 ("acca")
"aba" -&gt; index 1 ("caca"), index 2 ("bbbb"), index 3 ("caca")
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> words = ["abba","baab"], target = "bab"
<strong>Output:</strong> 4
<strong>Explanation:</strong> There are 4 ways to form target.
"bab" -&gt; index 0 ("baab"), index 1 ("baab"), index 2 ("abba")
"bab" -&gt; index 0 ("baab"), index 1 ("baab"), index 3 ("baab")
"bab" -&gt; index 0 ("baab"), index 2 ("baab"), index 3 ("baab")
"bab" -&gt; index 1 ("abba"), index 2 ("baab"), index 3 ("baab")
</pre>



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



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



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> words = ["abab","baba","abba","baab"], target = "abba"
<strong>Output:</strong> 16
</pre>



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



<ul><li><code>1 &lt;= words.length &lt;= 1000</code></li><li><code>1 &lt;= words[i].length &lt;= 1000</code></li><li>All strings in&nbsp;<code>words</code>&nbsp;have the same length.</li><li><code>1 &lt;= target.length &lt;= 1000</code></li><li><code>words[i]</code>&nbsp;and&nbsp;<code>target</code>&nbsp;contain only lowercase English letters.</li></ul>



<h2><strong>Solution: DP</strong></h2>



<p>dp[i][j] := # of ways to form target[0~j] where the j-th letter is from the i-th column of words.<br>count[i][j] := # of words that have word[i] == target[j]</p>



<p>dp[i][j] = dp[i-1][j-1] * count[i][j]</p>



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



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

<pre class="crayon-plain-tag">class Solution {
public:
  int numWays(vector&lt;string&gt;&amp; words, string target) {
    constexpr int kMod = 1e9 + 7;
    const int n = target.length();
    const int m = words[0].length();
    
    vector&lt;long&gt; dp(n); // dp[j] = # of ways to form t[0~j]
    for (int i = 0; i &lt; m; ++i) {
      vector&lt;int&gt; count(26);
      for (const string&amp; word: words)
        ++count[word[i] - 'a'];      
      for (int j = min(i, n - 1); j &gt;= 0; --j)
        dp[j] = (dp[j] + (j &gt; 0 ? dp[j - 1] : 1) * 
                    count[target[j] - 'a']) % kMod;
    }
    return dp[n - 1];
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1639-number-of-ways-to-form-a-target-string-given-a-dictionary/">花花酱 LeetCode 1639. Number of Ways to Form a Target String Given a Dictionary</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1639-number-of-ways-to-form-a-target-string-given-a-dictionary/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[<p>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;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-1391-check-if-there-is-a-valid-path-in-a-grid/">花花酱 LeetCode 1391. Check if There is a Valid Path in a Grid</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></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><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 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 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 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><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><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="crayon-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>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-1391-check-if-there-is-a-valid-path-in-a-grid/">花花酱 LeetCode 1391. Check if There is a Valid Path in a Grid</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></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 1380. Lucky Numbers in a Matrix</title>
		<link>https://zxi.mytechroad.com/blog/algorithms/array/leetcode-1380-lucky-numbers-in-a-matrix/</link>
					<comments>https://zxi.mytechroad.com/blog/algorithms/array/leetcode-1380-lucky-numbers-in-a-matrix/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 15 Mar 2020 08:05:03 +0000</pubDate>
				<category><![CDATA[Array]]></category>
		<category><![CDATA[easy]]></category>
		<category><![CDATA[matrix]]></category>
		<category><![CDATA[O(mn)]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=6494</guid>

					<description><![CDATA[<p>Given a&#160;m * n&#160;matrix of&#160;distinct&#160;numbers, return all lucky numbers in the&#160;matrix in&#160;any&#160;order. A lucky number is an element of the matrix such that it is&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/algorithms/array/leetcode-1380-lucky-numbers-in-a-matrix/">花花酱 LeetCode 1380. Lucky Numbers in a Matrix</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Given a&nbsp;<code>m * n</code>&nbsp;matrix of&nbsp;<strong>distinct&nbsp;</strong>numbers, return all lucky numbers in the&nbsp;matrix in&nbsp;<strong>any&nbsp;</strong>order.</p>



<p>A lucky number is an element of the matrix such that it is the minimum element in its row and maximum in its column.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> matrix = [[3,7,8],[9,11,13],[15,16,17]]
<strong>Output:</strong> [15]
<strong>Explanation:</strong> 15 is the only lucky number since it is the minimum in its row and the maximum in its column
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> matrix = [[1,10,4,2],[9,3,8,7],[15,16,17,12]]
<strong>Output:</strong> [12]
<strong>Explanation:</strong> 12 is the only lucky number since it is the minimum in its row and the maximum in its column.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> matrix = [[7,8],[1,2]]
<strong>Output:</strong> [7]
</pre>



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



<ul><li><code>m == mat.length</code></li><li><code>n == mat[i].length</code></li><li><code>1 &lt;= n, m &lt;= 50</code></li><li><code>1 &lt;=&nbsp;matrix[i][j]&nbsp;&lt;= 10^5</code>.</li><li>All elements in the matrix are distinct.</li></ul>



<h2><strong>Solution: Pre-processing</strong></h2>



<p>Two pass. First pass, record the min val of each row, and max val of each column.<br>Second pass, identify lucky numbers.</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="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  vector&lt;int&gt; luckyNumbers (vector&lt;vector&lt;int&gt;&gt;&amp; matrix) {
    const int m = matrix.size();
    const int n = matrix[0].size();
    vector&lt;int&gt; rows(m, INT_MAX);
    vector&lt;int&gt; cols(n, INT_MIN);
    for (int i = 0; i &lt; m; ++i)
      for (int j = 0; j &lt; n; ++j) {
        rows[i] = min(rows[i], matrix[i][j]);
        cols[j] = max(cols[j], matrix[i][j]);
      }
    vector&lt;int&gt; ans;
    for (int i = 0; i &lt; m; ++i)
      for (int j = 0; j &lt; n; ++j) 
        if (matrix[i][j] == rows[i] &amp;&amp;
            matrix[i][j] == cols[j])
          ans.push_back(matrix[i][j]);
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/algorithms/array/leetcode-1380-lucky-numbers-in-a-matrix/">花花酱 LeetCode 1380. Lucky Numbers in a Matrix</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/algorithms/array/leetcode-1380-lucky-numbers-in-a-matrix/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[<p>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;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-1368-minimum-cost-to-make-at-least-one-valid-path-in-a-grid/">花花酱 LeetCode 1368. Minimum Cost to Make at Least One Valid Path in a Grid</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></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 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; encrypted-media; gyroscope; picture-in-picture" 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><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 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 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 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><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><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="crayon-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="crayon-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><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="crayon-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>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-1368-minimum-cost-to-make-at-least-one-valid-path-in-a-grid/">花花酱 LeetCode 1368. Minimum Cost to Make at Least One Valid Path in a Grid</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></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 1314. Matrix Block Sum</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1314-matrix-block-sum/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1314-matrix-block-sum/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 11 Jan 2020 18:28:35 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[matrix]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[O(mn)]]></category>
		<category><![CDATA[query]]></category>
		<category><![CDATA[range sum]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=6071</guid>

					<description><![CDATA[<p>Given a&#160;m * n&#160;matrix&#160;mat&#160;and an integer&#160;K, return a matrix&#160;answer&#160;where each&#160;answer[i][j]&#160;is the sum of all elements&#160;mat[r][c]&#160;for&#160;i - K &#60;= r &#60;= i + K, j -&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1314-matrix-block-sum/">花花酱 LeetCode 1314. Matrix Block Sum</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Given a&nbsp;<code>m * n</code>&nbsp;matrix&nbsp;<code>mat</code>&nbsp;and an integer&nbsp;<code>K</code>, return a matrix&nbsp;<code>answer</code>&nbsp;where each&nbsp;<code>answer[i][j]</code>&nbsp;is the sum of all elements&nbsp;<code>mat[r][c]</code>&nbsp;for&nbsp;<code>i - K &lt;= r &lt;= i + K, j - K &lt;= c &lt;= j + K</code>, and&nbsp;<code>(r, c)</code>&nbsp;is a valid position in the matrix.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> mat = [[1,2,3],[4,5,6],[7,8,9]], K = 1
<strong>Output:</strong> [[12,21,16],[27,45,33],[24,39,28]]
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> mat = [[1,2,3],[4,5,6],[7,8,9]], K = 2
<strong>Output:</strong> [[45,45,45],[45,45,45],[45,45,45]]
</pre>



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



<ul><li><code>m ==&nbsp;mat.length</code></li><li><code>n ==&nbsp;mat[i].length</code></li><li><code>1 &lt;= m, n, K &lt;= 100</code></li><li><code>1 &lt;= mat[i][j] &lt;= 100</code></li></ul>



<h2><strong>Solution: 2D range query</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="crayon-plain-tag">// Author: Huahua, 20 ms
class Solution {
public:
  vector&lt;vector&lt;int&gt;&gt; matrixBlockSum(vector&lt;vector&lt;int&gt;&gt;&amp; mat, int K) {
    const int n = mat.size();
    const int m = mat[0].size();
    vector&lt;vector&lt;int&gt;&gt; dp(n + 1, vector&lt;int&gt;(m + 1));
    for (int y = 1; y &lt;= n; ++y)
      for (int x = 1; x &lt;= m; ++x)
        dp[y][x] = dp[y - 1][x] + dp[y][x - 1] + mat[y - 1][x - 1] - dp[y - 1][x - 1];
    auto ans = mat;
    for (int y = 1; y &lt;= n; ++y)
      for (int x = 1; x &lt;= m; ++x) {
        int x1 = max(1, x - K);
        int x2 = min(m, x + K);
        int y1 = max(1, y - K);
        int y2 = min(n, y + K);
        ans[y - 1][x - 1] = dp[y2][x2] - dp[y1 - 1][x2] - dp[y2][x1 - 1] + dp[y1 - 1][x1 - 1];
      }
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1314-matrix-block-sum/">花花酱 LeetCode 1314. Matrix Block Sum</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1314-matrix-block-sum/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1267. Count Servers that Communicate</title>
		<link>https://zxi.mytechroad.com/blog/algorithms/array/leetcode-1267-count-servers-that-communicate/</link>
					<comments>https://zxi.mytechroad.com/blog/algorithms/array/leetcode-1267-count-servers-that-communicate/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 24 Nov 2019 07:47:55 +0000</pubDate>
				<category><![CDATA[Array]]></category>
		<category><![CDATA[counting]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[O(mn)]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=5837</guid>

					<description><![CDATA[<p>You are given a map of a server center, represented as a&#160;m * n&#160;integer matrix&#160;grid, where 1 means that on that cell there is a&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/algorithms/array/leetcode-1267-count-servers-that-communicate/">花花酱 LeetCode 1267. Count Servers that Communicate</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>You are given a map of a server center, represented as a&nbsp;<code>m * n</code>&nbsp;integer matrix&nbsp;<code>grid</code>, where 1 means that on that cell there is a server and 0 means that it is no server. Two servers are said to communicate if they are on the same row or on the same column.<br><br>Return the number of servers&nbsp;that communicate with any other server.</p>



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



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



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



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



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



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



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



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



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



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



<ul><li><code>m == grid.length</code></li><li><code>n == grid[i].length</code></li><li><code>1 &lt;= m &lt;= 250</code></li><li><code>1 &lt;= n &lt;= 250</code></li><li><code>grid[i][j] == 0 or 1</code></li></ul>



<h2><strong>Solution: Counting</strong></h2>



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



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



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

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  int countServers(vector&lt;vector&lt;int&gt;&gt;&amp; grid) {
    const size_t m = grid.size();
    const size_t n = grid[0].size();
    vector&lt;int&gt; rows(m);
    vector&lt;int&gt; cols(n);
    for (size_t i = 0; i &lt; m; ++i)
      for (size_t j = 0; j &lt; n; ++j) {
        rows[i] += grid[i][j];
        cols[j] += grid[i][j];
      }
    int ans = 0;
     for (size_t i = 0; i &lt; m; ++i)
      for (size_t j = 0; j &lt; n; ++j)
        ans += (rows[i] &gt; 1 || cols[j] &gt; 1) ? grid[i][j] : 0;
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/algorithms/array/leetcode-1267-count-servers-that-communicate/">花花酱 LeetCode 1267. Count Servers that Communicate</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/algorithms/array/leetcode-1267-count-servers-that-communicate/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1237. Find Positive Integer Solution for a Given Equation</title>
		<link>https://zxi.mytechroad.com/blog/brute-force/leetcode-1237-find-positive-integer-solution-for-a-given-equation/</link>
					<comments>https://zxi.mytechroad.com/blog/brute-force/leetcode-1237-find-positive-integer-solution-for-a-given-equation/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 28 Oct 2019 03:16:56 +0000</pubDate>
				<category><![CDATA[Brute Force]]></category>
		<category><![CDATA[brute force]]></category>
		<category><![CDATA[easy]]></category>
		<category><![CDATA[interactive]]></category>
		<category><![CDATA[O(mn)]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=5785</guid>

					<description><![CDATA[<p>Given a&#160;function&#160;&#160;f(x, y)&#160;and a value&#160;z, return all positive integer&#160;pairs&#160;x&#160;and&#160;y&#160;where&#160;f(x,y) == z. The function is constantly increasing, i.e.: f(x, y) &#60; f(x + 1, y) f(x,&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/brute-force/leetcode-1237-find-positive-integer-solution-for-a-given-equation/">花花酱 LeetCode 1237. Find Positive Integer Solution for a Given Equation</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Given a&nbsp;function&nbsp;&nbsp;<code>f(x, y)</code>&nbsp;and a value&nbsp;<code>z</code>, return all positive integer&nbsp;pairs&nbsp;<code>x</code>&nbsp;and&nbsp;<code>y</code>&nbsp;where&nbsp;<code>f(x,y) == z</code>.</p>



<p>The function is constantly increasing, i.e.:</p>



<ul><li><code>f(x, y) &lt; f(x + 1, y)</code></li><li><code>f(x, y) &lt; f(x, y + 1)</code></li></ul>



<p>The function interface is defined like this:&nbsp;</p>



<pre class="wp-block-preformatted;crayon:false">interface CustomFunction {
public:
&nbsp; // Returns positive integer f(x, y) for any given positive integer x and y.
&nbsp; int f(int x, int y);
};
</pre>



<p>For custom testing purposes you&#8217;re given an integer&nbsp;<code>function_id</code>&nbsp;and a target&nbsp;<code>z</code>&nbsp;as input, where&nbsp;<code>function_id</code>&nbsp;represent one function from an secret internal list, on the examples you&#8217;ll know only two functions from the list. &nbsp;</p>



<p>You may return the solutions in any order.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> function_id = 1, z = 5
<strong>Output:</strong> [[1,4],[2,3],[3,2],[4,1]]
<strong>Explanation:</strong>&nbsp;function_id = 1 means that f(x, y) = x + y</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> function_id = 2, z = 5
<strong>Output:</strong> [[1,5],[5,1]]
<strong>Explanation:</strong>&nbsp;function_id = 2 means that f(x, y) = x * y
</pre>



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



<ul><li><code>1 &lt;= function_id &lt;= 9</code></li><li><code>1 &lt;= z &lt;= 100</code></li><li>It&#8217;s guaranteed that the solutions of&nbsp;<code>f(x, y) == z</code>&nbsp;will be on the range&nbsp;<code>1 &lt;= x, y &lt;= 1000</code></li><li>It&#8217;s also guaranteed that&nbsp;<code>f(x, y)</code>&nbsp;will fit in 32 bit signed integer if&nbsp;<code>1 &lt;= x, y &lt;= 1000</code></li></ul>



<h2><strong>Solution1 : Brute Force</strong></h2>



<p>Time complexity: O(1000*1000)<br>Space complexity: O(1)</p>



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

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  vector&lt;vector&lt;int&gt;&gt; findSolution(CustomFunction&amp; customfunction, int z) {
    vector&lt;vector&lt;int&gt;&gt; ans;    
    for (int x = 1; x &lt;= 1000; ++x) {
      if (customfunction.f(x, 1) &gt; z) break;
      for (int y = 1; y &lt;= 1000; ++y) {
        int t = customfunction.f(x, y);
        if (t &gt; z) break;
        if (t == z) ans.push_back({x, y});        
      }
    }
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/brute-force/leetcode-1237-find-positive-integer-solution-for-a-given-equation/">花花酱 LeetCode 1237. Find Positive Integer Solution for a Given Equation</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/brute-force/leetcode-1237-find-positive-integer-solution-for-a-given-equation/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 130. Surrounded Regions</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-130-surrounded-regions/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-130-surrounded-regions/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Thu, 10 Oct 2019 04:44:39 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[board]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[O(mn)]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=5743</guid>

					<description><![CDATA[<p>Given a 2D board containing&#160;'X'&#160;and&#160;'O'&#160;(the letter O), capture all regions surrounded by&#160;'X'. A region is captured by flipping all&#160;'O's into&#160;'X's in that surrounded region. Example:&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-130-surrounded-regions/">花花酱 LeetCode 130. Surrounded Regions</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></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 130. Surrounded Regions - 刷题找工作 EP274" width="500" height="375" src="https://www.youtube.com/embed/kyvGkcXs_rE?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div></figure>



<p>Given a 2D board containing&nbsp;<code>'X'</code>&nbsp;and&nbsp;<code>'O'</code>&nbsp;(<strong>the letter O</strong>), capture all regions surrounded by&nbsp;<code>'X'</code>.</p>



<p>A region is captured by flipping all&nbsp;<code>'O'</code>s into&nbsp;<code>'X'</code>s in that surrounded region.</p>



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



<pre class="wp-block-preformatted;crayon:false">X X X X
X O O X
X X O X
X O X X
</pre>



<p>After running your function, the board should be:</p>



<pre class="wp-block-preformatted;crayon:false">X X X X
X X X X
X X X X
X O X X
</pre>



<p><strong>Explanation:</strong></p>



<p>Surrounded regions shouldn’t be on the border, which means that any&nbsp;<code>'O'</code>&nbsp;on the border of the board are not flipped to&nbsp;<code>'X'</code>. Any&nbsp;<code>'O'</code>&nbsp;that is not on the border and it is not connected to an&nbsp;<code>'O'</code>&nbsp;on the border will be flipped to&nbsp;<code>'X'</code>. Two cells are connected if they are adjacent cells connected horizontally or vertically.</p>



<h2><strong>Solution: DFS</strong></h2>



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



<p>Only starts DFS at border cells of O.</p>



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

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  void solve(vector&lt;vector&lt;char&gt;&gt;&amp; board) {
    const int m = board.size();
    if (m == 0) return;
    const int n = board[0].size();    
    
    function&lt;void(int, int)&gt; dfs = [&amp;](int x, int y) {
      if (x &lt; 0 || x &gt;= n || y &lt; 0 || y &gt;= m || board[y][x] != 'O') return;
      board[y][x] = 'G'; // mark it as good      
      dfs(x - 1, y);
      dfs(x + 1, y);
      dfs(x, y - 1);
      dfs(x, y + 1);
    };
    
    for (int y = 0; y &lt; m; ++y)
      dfs(0, y), dfs(n - 1, y);    
    
    for (int x = 0; x &lt; n; ++x)
      dfs(x, 0), dfs(x, m - 1);    
    
    map&lt;char, char&gt; v{{'G','O'},{'O','X'}, {'X','X'}};
    for (int y = 0; y &lt; m; ++y)
      for (int x = 0; x &lt; n; ++x)
        board[y][x] = v[board[y][x]];
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-130-surrounded-regions/">花花酱 LeetCode 130. Surrounded Regions</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-130-surrounded-regions/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1143. Longest Common Subsequence</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1143-longest-common-subsequence/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1143-longest-common-subsequence/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Fri, 30 Aug 2019 06:24:35 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[dynamic programming]]></category>
		<category><![CDATA[LCS]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[O(mn)]]></category>
		<category><![CDATA[string]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=5504</guid>

					<description><![CDATA[<p>Given two strings&#160;text1&#160;and&#160;text2, return the length of their longest common subsequence. A&#160;subsequence&#160;of a string is a new string generated from the original string with some&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1143-longest-common-subsequence/">花花酱 LeetCode 1143. Longest Common Subsequence</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Given two strings&nbsp;<code>text1</code>&nbsp;and&nbsp;<code>text2</code>, return the length of their longest common subsequence.</p>



<p>A&nbsp;<em>subsequence</em>&nbsp;of a string is a new string generated from the original string with some characters(can be none) deleted without changing the relative order of the remaining characters. (eg, &#8220;ace&#8221; is a subsequence of &#8220;abcde&#8221; while &#8220;aec&#8221; is not).&nbsp;A&nbsp;<em>common subsequence</em>&nbsp;of two strings is a subsequence that is common to both strings.</p>



<p>If there is no common subsequence, return 0.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> text1 = "abcde", text2 = "ace" 
<strong>Output:</strong> 3  
<strong>Explanation:</strong> The longest common subsequence is "ace" and its length is 3.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> text1 = "abc", text2 = "abc"
<strong>Output:</strong> 3
<strong>Explanation:</strong> The longest common subsequence is "abc" and its length is 3.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> text1 = "abc", text2 = "def"
<strong>Output:</strong> 0
<strong>Explanation:</strong> There is no such common subsequence, so the result is 0.
</pre>



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



<ul><li><code>1 &lt;= text1.length &lt;= 1000</code></li><li><code>1 &lt;= text2.length &lt;= 1000</code></li><li>The input strings consist of lowercase English characters only.</li></ul>



<p><strong>Solution: DP</strong></p>



<p>Use dp[i][j] to represent the length of longest common sub-sequence of text1[0:i] and text2[0:j]<br>dp[i][j] = dp[i &#8211; 1][j &#8211; 1]  + 1 if text1[i &#8211; 1] == text2[j &#8211; 1] else max(dp[i][j &#8211; 1], dp[i &#8211; 1][j])</p>



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



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

<pre class="crayon-plain-tag">// Author: Huahua, 16ms 14.9 MB
class Solution {
public:
  int longestCommonSubsequence(string text1, string text2) {
    int m = text1.length();
    int n = text2.length();
    vector&lt;vector&lt;int&gt;&gt; dp(m + 1, vector&lt;int&gt;(n + 1));
    for (int i = 0; i &lt; m; ++i)
      for (int j = 0; j &lt; n; ++j)
        if (text1[i] == text2[j])
          dp[i + 1][j + 1] = dp[i][j] + 1;
        else
          dp[i + 1][j + 1] = max(dp[i][j + 1], dp[i + 1][j]);      
    return dp[m][n];
  }
};</pre>

</div><h2 class="tabtitle">C++/V2</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua, 8ms, 8.8MB
class Solution {
public:
  int longestCommonSubsequence(string text1, string text2) {
    int m = text1.length();
    int n = text2.length();    
    vector&lt;int&gt; dp(n + 1);    
    for (int i = 0; i &lt; m; ++i) {
      int prev = 0; // dp[i][j]
      for (int j = 0; j &lt; n; ++j) {        
        int curr = dp[j + 1]; // dp[i][j + 1]
        if (text1[i] == text2[j])
          // dp[i + 1][j + 1] = dp[i][j] + 1
          dp[j + 1] = prev + 1; 
        else
          // dp[i + 1][j + 1] = max(dp[i][j + 1], dp[i + 1][j])
          dp[j + 1] = max(curr, dp[j]);
        prev = curr;
      }    
    }    
    return dp[n]; // dp[m][n]
  }
};</pre>

</div><h2 class="tabtitle">C++/V3</h2>
<div class="tabcontent">

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  int longestCommonSubsequence(string text1, string text2) {
    int m = text1.length();
    int n = text2.length();    
    vector&lt;int&gt; dp1(n + 1);
    vector&lt;int&gt; dp2(n + 1);
    for (int i = 0; i &lt; m; ++i) {      
      for (int j = 0; j &lt; n; ++j)
        if (text1[i] == text2[j])
          dp2[j + 1] = dp1[j] + 1; 
        else          
          dp2[j + 1] = max(dp1[j + 1], dp2[j]);              
      swap(dp1, dp2);
    }    
    return dp1[n];
  }
};</pre>
</div></div>



<p></p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1143-longest-common-subsequence/">花花酱 LeetCode 1143. Longest Common Subsequence</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1143-longest-common-subsequence/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 463. Island Perimeter</title>
		<link>https://zxi.mytechroad.com/blog/math/leetcode-463-island-perimeter/</link>
					<comments>https://zxi.mytechroad.com/blog/math/leetcode-463-island-perimeter/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Fri, 17 Aug 2018 16:25:05 +0000</pubDate>
				<category><![CDATA[Math]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[O(mn)]]></category>
		<category><![CDATA[perimeter]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=3576</guid>

					<description><![CDATA[<p>Problem You are given a map in form of a two-dimensional integer grid where 1 represents land and 0 represents water. Grid cells are connected&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/math/leetcode-463-island-perimeter/">花花酱 LeetCode 463. Island Perimeter</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><iframe width="500" height="375" src="https://www.youtube.com/embed/ddFvTWmVUEA?feature=oembed" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></p>
<h1>Problem</h1>
<p>You are given a map in form of a two-dimensional integer grid where 1 represents land and 0 represents water. Grid cells are connected horizontally/vertically (not diagonally). The grid is completely surrounded by water, and there is exactly one island (i.e., one or more connected land cells). The island doesn&#8217;t have &#8220;lakes&#8221; (water inside that isn&#8217;t connected to the water around the island). One cell is a square with side length 1. The grid is rectangular, width and height don&#8217;t exceed 100. Determine the perimeter of the island.</p>
<p><b>Example:</b></p>
<pre class="crayon:false">[[0,1,0,0],
 [1,1,1,0],
 [0,1,0,0],
 [1,1,0,0]]

Answer: 16
Explanation: The perimeter is the 16 yellow stripes in the image below:
<img src="https://leetcode.com/static/images/problemset/island.png" />
</pre>
<h1><strong>Solution: Counting</strong></h1>
<p>If a land has 0 neighbour, it contributes 4 to the perimeter</p>
<p>If a land has 1 neighbour, it contributes 3 to the perimeter</p>
<p>If a land has 2 neighbours, it contributes 2 to the perimeter</p>
<p>If a land has 3 neighbours, it contributes 1 to the perimeter</p>
<p>If a land has 4 neighbours, it contributes 0 to the perimeter</p>
<p>perimeter = area * 4 &#8211; total_neighbours</p>
<p>Time complexity: O(mn)</p>
<p>Space complexity: O(1)</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 148 ms
class Solution {
public:
  int islandPerimeter(vector&lt;vector&lt;int&gt;&gt;&amp; grid) {
    if (grid.empty()) return 0;
    int m = grid.size();
    int n = grid[0].size();
    int area = 0;
    int conn = 0;

    for (int y = 0; y &lt; m; ++y)
      for (int x = 0; x &lt; n; ++x)
        if (grid[y][x] == 1) {
          ++area;
          if (y &gt; 0 &amp;&amp; grid[y - 1][x] == 1) ++conn;
          if (x &gt; 0 &amp;&amp; grid[y][x - 1] == 1) ++conn;
        }

    return area*4 - conn*2;
  }
};</pre><p>&nbsp;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/math/leetcode-463-island-perimeter/">花花酱 LeetCode 463. Island Perimeter</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/math/leetcode-463-island-perimeter/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 566. Reshape the Matrix</title>
		<link>https://zxi.mytechroad.com/blog/algorithms/array/leetcode-566-reshape-the-matrix/</link>
					<comments>https://zxi.mytechroad.com/blog/algorithms/array/leetcode-566-reshape-the-matrix/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Thu, 16 Aug 2018 15:54:55 +0000</pubDate>
				<category><![CDATA[Array]]></category>
		<category><![CDATA[easy]]></category>
		<category><![CDATA[matrix]]></category>
		<category><![CDATA[O(mn)]]></category>
		<category><![CDATA[reshape]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=3547</guid>

					<description><![CDATA[<p>Problem In MATLAB, there is a very useful function called &#8216;reshape&#8217;, which can reshape a matrix into a new one with different size but keep&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/algorithms/array/leetcode-566-reshape-the-matrix/">花花酱 LeetCode 566. Reshape the Matrix</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><iframe width="500" height="375" src="https://www.youtube.com/embed/tI8M9GO4Kvo?feature=oembed" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></p>
<h1>Problem</h1>
<p>In MATLAB, there is a very useful function called &#8216;reshape&#8217;, which can reshape a matrix into a new one with different size but keep its original data.</p>
<p>You&#8217;re given a matrix represented by a two-dimensional array, and two <b>positive</b> integers <b>r</b> and <b>c</b> representing the <b>row</b> number and <b>column</b> number of the wanted reshaped matrix, respectively.</p>
<p>The reshaped matrix need to be filled with all the elements of the original matrix in the same <b>row-traversing</b> order as they were.</p>
<p>If the &#8216;reshape&#8217; operation with given parameters is possible and legal, output the new reshaped matrix; Otherwise, output the original matrix.</p>
<p><b>Example 1:</b></p>
<pre class="crayon:false"><b>Input:</b> 
nums = 
[[1,2],
 [3,4]]
r = 1, c = 4
<b>Output:</b> 
[[1,2,3,4]]
<b>Explanation:</b>
The <b>row-traversing</b> of nums is [1,2,3,4]. The new reshaped matrix is a 1 * 4 matrix, fill it row by row by using the previous list.
</pre>
<p><b>Example 2:</b></p>
<pre class="crayon:false"><b>Input:</b> 
nums = 
[[1,2],
 [3,4]]
r = 2, c = 4
<b>Output:</b> 
[[1,2],
 [3,4]]
<b>Explanation:</b>
There is no way to reshape a 2 * 2 matrix to a 2 * 4 matrix. So output the original matrix.
</pre>
<p><b>Note:</b></p>
<ol>
<li>The height and width of the given matrix is in range [1, 100].</li>
<li>The given r and c are all positive.</li>
</ol>
<h1>Solution1: Brute Force</h1>
<p>Time complexity: O(mn)</p>
<p>Space complexity: O(mn)</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 32 ms
class Solution {
public:
    vector&lt;vector&lt;int&gt;&gt; matrixReshape(vector&lt;vector&lt;int&gt;&gt;&amp; nums, int r, int c) {
        if (nums.size() == 0) return nums;
        int m = nums.size();
        int n = nums[0].size();
        if (m * n != r * c) return nums;
        
        // new matrix r*c
        vector&lt;vector&lt;int&gt;&gt; ans(r, vector&lt;int&gt;(c));
        for(int i = 0; i &lt; m * n;++i) {
            int src_y = i / n;
            int src_x = i % n;
            int dst_y = i / c;
            int dst_x = i % c;
            ans[dst_y][dst_x] = nums[src_y][src_x];
        }
        
        return ans;
    }
};</pre><p>&nbsp;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/algorithms/array/leetcode-566-reshape-the-matrix/">花花酱 LeetCode 566. Reshape the Matrix</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/algorithms/array/leetcode-566-reshape-the-matrix/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 174. Dungeon Game</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-174-dungeon-game/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-174-dungeon-game/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Thu, 16 Aug 2018 15:45:07 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[grid]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[O(mn)]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=3543</guid>

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

					<description><![CDATA[<p>Problem Given s1, s2, s3, find whether s3 is formed by the interleaving of s1 and s2. Example 1: Input: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac" Output: true Example 2:&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-97-interleaving-string/">花花酱 LeetCode 97. Interleaving String</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h1><strong>Problem</strong></h1>
<p>Given <em>s1</em>, <em>s2</em>, <em>s3</em>, find whether <em>s3</em> is formed by the interleaving of <em>s1</em> and <em>s2</em>.</p>
<p><strong>Example 1:</strong></p>
<pre class="crayon:false"><strong>Input:</strong> s1 = "aabcc", s2 = "dbbca", <em>s3</em> = "aadbbcbcac"
<strong>Output:</strong> true
</pre>
<p><strong>Example 2:</strong></p>
<pre class="crayon:false"><strong>Input:</strong> s1 = "aabcc", s2 = "dbbca", <em>s3</em> = "aadbbbaccc"
<strong>Output:</strong> false
</pre>
<h1><strong>Solution: DP</strong></h1>
<p>Subproblems : whether s3[0:i+j] can be formed by interleaving s1[0:i] and s2[0:j].</p>
<p>Time complexity: O(mn)</p>
<p>Space complexity: O(mn)</p><pre class="crayon-plain-tag">// Author: Huhaua
// Running time: 0 ms
class Solution {
public:
  bool isInterleave(string s1, string s2, string s3) {
    int l1 = s1.length();
    int l2 = s2.length();
    int l3 = s3.length();
    if (l1 + l2 != l3) return false;
    // dp[i][j]: whehter s3[0:i+j] is a interleva of s1[0:i] and s2[0:j]
    vector&lt;vector&lt;int&gt;&gt; dp(l1 + 1, vector&lt;int&gt;(l2 + 1));
    dp[0][0] = true;
    for (int i = 0; i &lt;= l1; ++i)
      for (int j = 0; j &lt;= l2; ++j) {        
        if (i &gt; 0) dp[i][j] |= dp[i - 1][j] &amp;&amp; s1[i - 1] == s3[i + j - 1];
        if (j &gt; 0) dp[i][j] |= dp[i][j - 1] &amp;&amp; s2[j - 1] == s3[i + j - 1];        
      }
    return dp[l1][l2];
  }
};</pre><p>Recursion + Memorization</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 0 ms
class Solution {
public:
  bool isInterleave(string s1, string s2, string s3) {
    m_ = vector&lt;vector&lt;int&gt;&gt;(s1.length() + 1, vector&lt;int&gt;(s2.length() + 1, INT_MIN));
    return dp(s1, s1.length(), s2, s2.length(), s3, s3.length());
  }
private:
  // m_[i][j]: whehter s3[0:i+j] is a interleva of s1[0:i] and s2[0:j]
  vector&lt;vector&lt;int&gt;&gt; m_;
  
  bool dp(const string&amp; s1, int l1, const string&amp; s2, int l2, const string&amp; s3, int l3) {
    if (l1 + l2 != l3) return false;
    if (l1 == 0 &amp;&amp; l2 == 0) return true;
    if (m_[l1][l2] != INT_MIN) return m_[l1][l2];
    if (l1 &gt; 0 &amp; s3[l3 - 1] == s1[l1 - 1] &amp;&amp; dp(s1, l1 - 1, s2, l2, s3, l3 - 1)
      ||l2 &gt; 0 &amp; s3[l3 - 1] == s2[l2 - 1] &amp;&amp; dp(s1, l1, s2, l2 - 1, s3, l3 - 1))
      m_[l1][l2] = 1;
    else
      m_[l1][l2] = 0;
    return m_[l1][l2];
  }
};</pre><p>&nbsp;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-97-interleaving-string/">花花酱 LeetCode 97. Interleaving String</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-97-interleaving-string/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
