<?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>path Archives - Huahua&#039;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/tag/path/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog/tag/path/</link>
	<description></description>
	<lastBuildDate>Sun, 05 Dec 2021 16:59:52 +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>path Archives - Huahua&#039;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog/tag/path/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>花花酱 LeetCode 2096. Step-By-Step Directions From a Binary Tree Node to Another</title>
		<link>https://zxi.mytechroad.com/blog/tree/leetcode-2096-step-by-step-directions-from-a-binary-tree-node-to-another/</link>
					<comments>https://zxi.mytechroad.com/blog/tree/leetcode-2096-step-by-step-directions-from-a-binary-tree-node-to-another/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 05 Dec 2021 08:11:36 +0000</pubDate>
				<category><![CDATA[Tree]]></category>
		<category><![CDATA[LCA]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[path]]></category>
		<category><![CDATA[recursion]]></category>
		<category><![CDATA[shortest path]]></category>
		<category><![CDATA[tree]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9023</guid>

					<description><![CDATA[<p>You are given the&#160;root&#160;of a&#160;binary tree&#160;with&#160;n&#160;nodes. Each node is uniquely assigned a value from&#160;1&#160;to&#160;n. You are also given an integer&#160;startValue&#160;representing the value of the start&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/tree/leetcode-2096-step-by-step-directions-from-a-binary-tree-node-to-another/">花花酱 LeetCode 2096. Step-By-Step Directions From a Binary Tree Node to Another</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 the&nbsp;<code>root</code>&nbsp;of a&nbsp;<strong>binary tree</strong>&nbsp;with&nbsp;<code>n</code>&nbsp;nodes. Each node is uniquely assigned a value from&nbsp;<code>1</code>&nbsp;to&nbsp;<code>n</code>. You are also given an integer&nbsp;<code>startValue</code>&nbsp;representing the value of the start node&nbsp;<code>s</code>, and a different integer&nbsp;<code>destValue</code>&nbsp;representing the value of the destination node&nbsp;<code>t</code>.</p>



<p>Find the&nbsp;<strong>shortest path</strong>&nbsp;starting from node&nbsp;<code>s</code>&nbsp;and ending at node&nbsp;<code>t</code>. Generate step-by-step directions of such path as a string consisting of only the&nbsp;<strong>uppercase</strong>&nbsp;letters&nbsp;<code>'L'</code>,&nbsp;<code>'R'</code>, and&nbsp;<code>'U'</code>. Each letter indicates a specific direction:</p>



<ul><li><code>'L'</code>&nbsp;means to go from a node to its&nbsp;<strong>left child</strong>&nbsp;node.</li><li><code>'R'</code>&nbsp;means to go from a node to its&nbsp;<strong>right child</strong>&nbsp;node.</li><li><code>'U'</code>&nbsp;means to go from a node to its&nbsp;<strong>parent</strong>&nbsp;node.</li></ul>



<p>Return&nbsp;<em>the step-by-step directions of the&nbsp;<strong>shortest path</strong>&nbsp;from node&nbsp;</em><code>s</code><em>&nbsp;to node</em>&nbsp;<code>t</code>.</p>



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



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> root = [5,1,2,3,null,6,4], startValue = 3, destValue = 6
<strong>Output:</strong> "UURL"
<strong>Explanation:</strong> The shortest path is: 3 → 1 → 5 → 2 → 6.
</pre>



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



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> root = [2,1], startValue = 2, destValue = 1
<strong>Output:</strong> "L"
<strong>Explanation:</strong> The shortest path is: 2 → 1.
</pre>



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



<ul><li>The number of nodes in the tree is&nbsp;<code>n</code>.</li><li><code>2 &lt;= n &lt;= 10<sup>5</sup></code></li><li><code>1 &lt;= Node.val &lt;= n</code></li><li>All the values in the tree are&nbsp;<strong>unique</strong>.</li><li><code>1 &lt;= startValue, destValue &lt;= n</code></li><li><code>startValue != destValue</code></li></ul>



<h2><strong>Solution: Lowest common ancestor</strong></h2>



<figure class="wp-block-image size-large"><a href="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/12/2096-ex1.png"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/12/2096-ex1.png" alt="" class="wp-image-9028" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/12/2096-ex1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2021/12/2096-ex1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2021/12/2096-ex1-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></figure>



<p>It&#8217;s no hard to see that the shortest path is from the start node to the lowest common ancestor (LCA) of (start, end), then to the end node. The key is to find the LCA while finding paths from root to two nodes.</p>



<p>We can use recursion to find/build a path from root to a target node.<br>The common prefix of these two paths is the path from root to the LCA that we need to remove from the shortest path.<br>e.g. <br>root to start &#8220;LLRLR&#8221;<br>root to dest &#8220;LLLR&#8221;<br>common prefix is &#8220;LL&#8221;, after removing, it becomes:<br>LCA to start &#8220;RLR&#8221;<br>LCA to dest &#8220;LR&#8221;<br>Final path becomes &#8220;UUU&#8221; + &#8220;LR&#8221; = &#8220;UUULR&#8221;</p>



<p>The final step is to replace the L/R with U for the start path since we are moving up and then concatenate with the target path.</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="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  string getDirections(TreeNode* root, int startValue, int destValue) {
    string startPath;
    string destPath;
    buildPath(root, startValue, startPath);
    buildPath(root, destValue, destPath);    
    // Remove common suffix (shared path from root to LCA)
    while (!startPath.empty() &amp;&amp; !destPath.empty() 
           &amp;&amp; startPath.back() == destPath.back()) {
      startPath.pop_back();
      destPath.pop_back();
    }
    reverse(begin(destPath), end(destPath));
    return string(startPath.size(), 'U') + destPath;
  }
private:
  bool buildPath(TreeNode* root, int t, string&amp; path) {
    if (!root) return false;
    if (root-&gt;val == t) return true;
    if (buildPath(root-&gt;left, t, path)) {
      path.push_back('L');
      return true;
    } else if (buildPath(root-&gt;right, t, path)) {
      path.push_back('R');
      return true;
    }
    return false;
  }
};</pre>
</div></div>



<p><br>  </p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/tree/leetcode-2096-step-by-step-directions-from-a-binary-tree-node-to-another/">花花酱 LeetCode 2096. Step-By-Step Directions From a Binary Tree Node to Another</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/tree/leetcode-2096-step-by-step-directions-from-a-binary-tree-node-to-another/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 257. Binary Tree Paths</title>
		<link>https://zxi.mytechroad.com/blog/tree/leetcode-257-binary-tree-paths/</link>
					<comments>https://zxi.mytechroad.com/blog/tree/leetcode-257-binary-tree-paths/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Thu, 30 Jan 2020 03:19:37 +0000</pubDate>
				<category><![CDATA[Tree]]></category>
		<category><![CDATA[easy]]></category>
		<category><![CDATA[O(n)]]></category>
		<category><![CDATA[path]]></category>
		<category><![CDATA[recursion]]></category>
		<category><![CDATA[tree]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=6171</guid>

					<description><![CDATA[<p>Given a binary tree, return all root-to-leaf paths. Note:&#160;A leaf is a node with no children. Example: Input: 1 / \ 2 3 \ 5&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/tree/leetcode-257-binary-tree-paths/">花花酱 LeetCode 257. Binary Tree Paths</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 binary tree, return all root-to-leaf paths.</p>



<p><strong>Note:</strong>&nbsp;A leaf is a node with no children.</p>



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



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

   1
 /   \
2     3
 \
  5

<strong>Output:</strong> ["1-&gt;2-&gt;5", "1-&gt;3"]

<strong>Explanation:</strong> All root-to-leaf paths are: 1-&gt;2-&gt;5, 1-&gt;3</pre>



<h2><strong>Solution: Recursion</strong></h2>



<p>Time complexity: O(n)<br>Space complexity: O(n) / output can be O(n^2)</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;string&gt; binaryTreePaths(TreeNode* root) {
    vector&lt;string&gt; ans;
    string s;
    function&lt;void(TreeNode*, int)&gt; preorder = [&amp;](TreeNode* node, int l) {
      if (!node) return;
      s += (l &gt; 0 ? &quot;-&gt;&quot; : &quot;&quot;) + to_string(node-&gt;val);
      if (!node-&gt;left &amp;&amp; !node-&gt;right)
        ans.push_back(s);
      preorder(node-&gt;left, s.size());
      preorder(node-&gt;right, s.size());
      while (s.size() != l) s.pop_back();
    };
    preorder(root, 0);
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/tree/leetcode-257-binary-tree-paths/">花花酱 LeetCode 257. Binary Tree Paths</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/tree/leetcode-257-binary-tree-paths/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1233. Remove Sub-Folders from the Filesystem</title>
		<link>https://zxi.mytechroad.com/blog/hashtable/leetcode-1233-remove-sub-folders-from-the-filesystem/</link>
					<comments>https://zxi.mytechroad.com/blog/hashtable/leetcode-1233-remove-sub-folders-from-the-filesystem/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Tue, 22 Oct 2019 05:38:07 +0000</pubDate>
				<category><![CDATA[Hashtable]]></category>
		<category><![CDATA[hsahtable]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[path]]></category>
		<category><![CDATA[string]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=5776</guid>

					<description><![CDATA[<p>Given a list of folders, remove all sub-folders in those folders and return in&#160;any order&#160;the folders after removing. If a&#160;folder[i]&#160;is located within&#160;another&#160;folder[j], it is called&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/hashtable/leetcode-1233-remove-sub-folders-from-the-filesystem/">花花酱 LeetCode 1233. Remove Sub-Folders from the Filesystem</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 list of folders, remove all sub-folders in those folders and return in&nbsp;<strong>any order</strong>&nbsp;the folders after removing.</p>



<p>If a&nbsp;<code>folder[i]</code>&nbsp;is located within&nbsp;another&nbsp;<code>folder[j]</code>, it is called a&nbsp;sub-folder&nbsp;of it.</p>



<p>The format of a path is&nbsp;one or more concatenated strings of the form:&nbsp;<code>/</code>&nbsp;followed by one or more lowercase English letters. For example,&nbsp;<code>/leetcode</code>&nbsp;and&nbsp;<code>/leetcode/problems</code>&nbsp;are valid paths while an empty string and&nbsp;<code>/</code>&nbsp;are not.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> folder = ["/a","/a/b","/c/d","/c/d/e","/c/f"]
<strong>Output:</strong> ["/a","/c/d","/c/f"]
<strong>Explanation:</strong> Folders "/a/b/" is a subfolder of "/a" and "/c/d/e" is inside of folder "/c/d" in our filesystem.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> folder = ["/a","/a/b/c","/a/b/d"]
<strong>Output:</strong> ["/a"]
<strong>Explanation:</strong> Folders "/a/b/c" and "/a/b/d/" will be removed because they are subfolders of "/a".
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> folder = ["/a/b/c","/a/b/ca","/a/b/d"]
<strong>Output:</strong> ["/a/b/c","/a/b/ca","/a/b/d"]
</pre>



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



<ul><li><code>1 &lt;= folder.length&nbsp;&lt;= 4 * 10^4</code></li><li><code>2 &lt;= folder[i].length &lt;= 100</code></li><li><code>folder[i]</code>&nbsp;contains only&nbsp;lowercase letters and &#8216;/&#8217;</li><li><code>folder[i]</code>&nbsp;always starts with character &#8216;/&#8217;</li><li>Each folder name is unique.</li></ul>



<h2><strong>Solution: HashTable</strong></h2>



<p>Time complexity: O(n*L)<br>Space complexity: O(n*L)</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;string&gt; removeSubfolders(vector&lt;string&gt;&amp; folder) {
    unordered_set&lt;string&gt; s(begin(folder), end(folder));
    vector&lt;string&gt; ans;
    for (const auto&amp; cur : folder) {
      string f = cur;
      bool valid = true;
      while (!f.empty() &amp;&amp; valid) {
        while (f.back() != '/') f.pop_back();
        f.pop_back();
        if (s.count(f)) valid = false;
      }
      if (valid) ans.push_back(cur);
    }
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/hashtable/leetcode-1233-remove-sub-folders-from-the-filesystem/">花花酱 LeetCode 1233. Remove Sub-Folders from the Filesystem</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/hashtable/leetcode-1233-remove-sub-folders-from-the-filesystem/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 778. Swim in Rising Water</title>
		<link>https://zxi.mytechroad.com/blog/heap/leetcode-778-swim-in-rising-water/</link>
					<comments>https://zxi.mytechroad.com/blog/heap/leetcode-778-swim-in-rising-water/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Fri, 01 Feb 2019 04:46:57 +0000</pubDate>
				<category><![CDATA[Heap]]></category>
		<category><![CDATA[head]]></category>
		<category><![CDATA[path]]></category>
		<category><![CDATA[priority queue]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=4750</guid>

					<description><![CDATA[<p>On an N x N&#160;grid, each square&#160;grid[i][j]&#160;represents the elevation at that point&#160;(i,j). Now rain starts to fall. At time&#160;t, the depth of the water everywhere&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/heap/leetcode-778-swim-in-rising-water/">花花酱 LeetCode 778. Swim in Rising Water</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 width="500" height="375" src="https://www.youtube.com/embed/umdk98ynLSY?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div></figure>



<p>On an N x N&nbsp;<code>grid</code>, each square&nbsp;<code>grid[i][j]</code>&nbsp;represents the elevation at that point&nbsp;<code>(i,j)</code>.</p>



<p>Now rain starts to fall. At time&nbsp;<code>t</code>, the depth of the water everywhere is&nbsp;<code>t</code>. You can swim from a square to another 4-directionally adjacent square if and only if the elevation of both squares individually are&nbsp;at most&nbsp;<code>t</code>. You can swim infinite distance in zero time. Of course, you must stay within the boundaries of the grid during your swim.</p>



<p>You start at the top left square&nbsp;<code>(0, 0)</code>. What is the least time until you can reach the bottom right square&nbsp;<code>(N-1, N-1)</code>?</p>



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



<pre class="wp-block-preformatted crayon:false"><strong>Input:</strong> [[0,2],[1,3]]
<strong>Output:</strong> 3
<strong>Explanation:</strong>
At time <code>0</code>, you are in grid location <code>(0, 0)</code>.
You cannot go anywhere else because 4-directionally adjacent neighbors have a higher elevation than t = 0.

You cannot reach point <code>(1, 1)</code> until time <code>3</code>.
When the depth of water is <code>3</code>, we can swim anywhere inside the grid.
</pre>



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



<pre class="wp-block-preformatted crayon:false"><strong>Input:</strong> [[0,1,2,3,4],[24,23,22,21,5],[12,13,14,15,16],[11,17,18,19,20],[10,9,8,7,6]]
<strong>Output:</strong> 16
<strong>Explanation:</strong>
<strong> 0  1  2  3  4</strong>
24 23 22 21  <strong>5</strong>
<strong>12 13 14 15 16</strong>
<strong>11</strong> 17 18 19 20
<strong>10  9  8  7  6</strong>

The final route is marked in bold.
We need to wait until time 16 so that (0, 0) and (4, 4) are connected.
</pre>



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



<ol><li><code>2 &lt;= N &lt;= 50</code>.</li><li>grid[i][j] is a permutation of [0, &#8230;, N*N &#8211; 1].</li></ol>



<h2><strong>Solution 1: Dijkstra&#8217;s Algorithm</strong></h2>



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



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

<pre class="crayon-plain-tag">// Author: Huahua, running time: 8 ms
class Solution {
public:
  int swimInWater(vector&lt;vector&lt;int&gt;&gt;&amp; grid) {
    const int n = grid.size();
    priority_queue&lt;pair&lt;int, int&gt;&gt; q; // {-time, y * N + x}
    q.push({-grid[0][0], 0 * n + 0});
    vector&lt;int&gt; seen(n * n);
    vector&lt;int&gt; dirs{-1, 0, 1, 0, -1};
    seen[0 * n + 0] = 1;
    while (!q.empty()) {
      auto node = q.top(); q.pop();
      int t = -node.first;
      int x = node.second % n;
      int y = node.second / n;      
      if (x == n - 1 &amp;&amp; y == n - 1) return t;
      for (int i = 0; i &lt; 4; ++i) {
        int tx = x + dirs[i];
        int ty = y + dirs[i + 1];
        if (tx &lt; 0 || ty &lt; 0 || tx &gt;= n || ty &gt;= n) continue;
        if (seen[ty * n + tx]) continue;
        seen[ty * n + tx] = 1;
        q.push({-max(t, grid[ty][tx]), ty * n + tx});
      }
    }
    return -1;
  }
};</pre>
</div></div>



<h2><strong>Solution 2: Binary Search + BFS</strong></h2>



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



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

<pre class="crayon-plain-tag">// Author: Huahua, running time: 8 ms
class Solution {
public:
  int swimInWater(vector&lt;vector&lt;int&gt;&gt;&amp; grid) {
    const int n = grid.size();
    auto hasPath = [&amp;grid, n](int t) {
      if (grid[0][0] &gt; t) return false;      
      queue&lt;int&gt; q;
      vector&lt;int&gt; seen(n * n);
      vector&lt;int&gt; dirs{1, 0, -1, 0, 1};
      q.push(0);
      
      while (!q.empty()) {
        const int x = q.front() % n;
        const int y = q.front() / n;
        q.pop();
        if (x == n - 1 &amp;&amp; y == n - 1) return true;
        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 || ty &lt; 0 || tx &gt;= n || ty &gt;= n || grid[ty][tx] &gt; t) continue;
          const int key = ty * n + tx;
          if (seen[key]) continue;
          seen[key] = 1;
          q.push(key);
        }
      }
      return false;
    };
    int l = 0;
    int r = n * n;
    while (l &lt; r) {
      int m = l + (r - l) / 2;
      if (hasPath(m)) {
        r = m;
      } else {
        l = m + 1;
      }
    }
    return l;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/heap/leetcode-778-swim-in-rising-water/">花花酱 LeetCode 778. Swim in Rising Water</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/heap/leetcode-778-swim-in-rising-water/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 931. Minimum Falling Path Sum</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-931-minimum-falling-path-sum/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-931-minimum-falling-path-sum/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 28 Oct 2018 15:45:22 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[path]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=4226</guid>

					<description><![CDATA[<p>Problem Given a square array of integers A, we want the minimum sum of a falling path through A. A falling path starts at any element in the first row, and chooses one&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-931-minimum-falling-path-sum/">花花酱 LeetCode 931. Minimum Falling Path 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[<h1><strong>Problem</strong></h1>
<p>Given a <strong>square</strong> array of integers <code>A</code>, we want the <strong>minimum</strong> sum of a <em>falling path</em> through <code>A</code>.</p>
<p>A falling path starts at any element in the first row, and chooses one element from each row.  The next row&#8217;s choice must be in a column that is different from the previous row&#8217;s column by at most one.</p>
<p>&nbsp;</p>
<p><strong>Example 1:</strong></p>
<pre class="crayon:false"><strong>Input: </strong><span id="example-input-1-1">[[1,2,3],[4,5,6],[7,8,9]]</span>
<strong>Output: </strong><span id="example-output-1">12</span>
<strong>Explanation: </strong>
The possible falling paths are:
</pre>
<ul>
<li><code>[1,4,7], [1,4,8], [1,5,7], [1,5,8], [1,5,9]</code></li>
<li><code>[2,4,7], [2,4,8], [2,5,7], [2,5,8], [2,5,9], [2,6,8], [2,6,9]</code></li>
<li><code>[3,5,7], [3,5,8], [3,5,9], [3,6,8], [3,6,9]</code></li>
</ul>
<p>The falling path with the smallest sum is <code>[1,4,7]</code>, so the answer is <code>12</code>.</p>
<p><strong>Note:</strong></p>
<ol>
<li><code>1 &lt;= A.length == A[0].length &lt;= 100</code></li>
<li><code>-100 &lt;= A[i][j] &lt;= 100</code></li>
</ol>
<h1><strong>Solution: DP</strong></h1>
<p>Time complexity: O(mn)</p>
<p>Space complexity: O(mn)</p>
<p><div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua, 12 ms
class Solution {
public:
  int minFallingPathSum(vector&lt;vector&lt;int&gt;&gt;&amp; A) {
    int n = A.size();
    int m = A[0].size();
    vector&lt;vector&lt;int&gt;&gt; dp(n + 2, vector&lt;int&gt;(m + 2));
          
    for (int i = 1; i &lt;= n; ++i) {
      dp[i][0] = dp[i][m + 1] = INT_MAX;
      for (int j = 1; j &lt;= m; ++j)
        dp[i][j] = *min_element(dp[i - 1].begin() + j - 1, 
                                dp[i - 1].begin() + j + 2) + A[i - 1][j - 1];      
    }
    return *min_element(dp[n].begin() + 1, dp[n].end() - 1);
  }
};</pre><p></div><h2 class="tabtitle">C++/in place</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua, 12 ms
class Solution {
public:
  int minFallingPathSum(vector&lt;vector&lt;int&gt;&gt;&amp; A) {
    int n = A.size();
    int m = A[0].size();    
          
    for (int i = 1; i &lt; n; ++i)
      for (int j = 0; j &lt; m; ++j) {
        int sum = A[i - 1][j];
        if (j &gt; 0) sum = min(sum, A[i - 1][j - 1]);
        if (j &lt; m - 1) sum = min(sum, A[i - 1][j + 1]);
        A[i][j] += sum;
      }
            
    return *min_element(begin(A.back()), end(A.back()));
  }
};</pre><p></div></div></p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-931-minimum-falling-path-sum/">花花酱 LeetCode 931. Minimum Falling Path 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-931-minimum-falling-path-sum/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 576. Out of Boundary Paths</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-576-out-of-boundary-paths/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-576-out-of-boundary-paths/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 02 Jun 2018 17:02:00 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[counting]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[path]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=2876</guid>

					<description><![CDATA[<p>Problem There is an m by n grid with a ball. Given the start coordinate (i,j) of the ball, you can move the ball to adjacent cell or cross the grid boundary in&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-576-out-of-boundary-paths/">花花酱 LeetCode 576. Out of Boundary Paths</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/92zh6XvqEgc?feature=oembed" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></p>
<h1><strong>Problem</strong></h1>
<p>There is an <b>m</b> by <b>n</b> grid with a ball. Given the start coordinate <b>(i,j)</b> of the ball, you can move the ball to <b>adjacent</b> cell or cross the grid boundary in four directions (up, down, left, right). However, you can <b>at most</b> move <b>N</b> times. Find out the number of paths to move the ball out of grid boundary. The answer may be very large, return it after mod 10<sup>9</sup> + 7.</p>
<p><b>Example 1:</b></p>
<pre class="crayon:false"><b>Input:</b>m = 2, n = 2, N = 2, i = 0, j = 0
<b>Output:</b> 6
<b>Explanation:</b>
<img src="https://leetcode.com/static/images/problemset/out_of_boundary_paths_1.png" width="40%" />
</pre>
<p><b>Example 2:</b></p>
<pre class="crayon:false"><b>Input:</b>m = 1, n = 3, N = 3, i = 0, j = 1
<b>Output:</b> 12
<b>Explanation:</b>
<img src="https://leetcode.com/static/images/problemset/out_of_boundary_paths_2.png" width="37%" />
</pre>
<p><b>Note:</b></p>
<ol>
<li>Once you move the ball out of boundary, you cannot move it back.</li>
<li>The length and height of the grid is in range [1,50].</li>
<li>N is in range [0,50].</li>
</ol>
<h1><img class="alignnone size-full wp-image-2881" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2018/06/576-ep194.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/06/576-ep194.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/06/576-ep194-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/06/576-ep194-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></h1>
<h1>Solution</h1>
<p>Time complexity: O(m*n + N * m * n)</p>
<p>Space complexity: O(N*m*n) -&gt; O(m*n)</p>
<p>C++</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 19 ms
class Solution {
public:
  int findPaths(int m, int n, int N, int i, int j) {
    constexpr int kMod = 1000000007;
    vector&lt;vector&lt;vector&lt;int&gt;&gt;&gt; dp(N + 1, vector&lt;vector&lt;int&gt;&gt;(m, vector&lt;int&gt;(n, 0)));
    vector&lt;int&gt; dirs{-1, 0, 1, 0, -1};
    for (int s = 1; s &lt;= N; ++s)
      for (int y = 0; y &lt; m; ++y)
        for (int x = 0; x &lt; n; ++x)
          for (int d = 0; d &lt; 4; ++d) {
            int tx = x + dirs[d];
            int ty = y + dirs[d + 1];            
            if (tx &lt; 0 || ty &lt; 0 || tx &gt;= n || ty &gt;= m)
              dp[s][y][x] += 1;
            else
              dp[s][y][x] = (dp[s][y][x] + dp[s - 1][ty][tx]) % kMod;
          }        
    return dp[N][i][j];
  }
};</pre><p></p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 16 ms
class Solution {
public:
  int findPaths(int m, int n, int N, int i, int j) {
    constexpr int kMod = 1000000007;
    vector&lt;vector&lt;int&gt;&gt; dp(m, vector&lt;int&gt;(n, 0));
    vector&lt;int&gt; dirs{-1, 0, 1, 0, -1};
    for (int s = 1; s &lt;= N; ++s) {
      vector&lt;vector&lt;int&gt;&gt; tmp(m, vector&lt;int&gt;(n, 0));
      for (int y = 0; y &lt; m; ++y)
        for (int x = 0; x &lt; n; ++x)
          for (int d = 0; d &lt; 4; ++d) {
            int tx = x + dirs[d];
            int ty = y + dirs[d + 1];            
            if (tx &lt; 0 || ty &lt; 0 || tx &gt;= n || ty &gt;= m)
              tmp[y][x] += 1;
            else
              tmp[y][x] = (tmp[y][x] + dp[ty][tx]) % kMod;
          }
      dp.swap(tmp);
    }
    return dp[i][j];
  }
};</pre><p>Recursion with memorization</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 4 ms
class Solution {
public:
  int findPaths(int m, int n, int N, int i, int j) {    
    m_ = m;
    n_ = n;
    dp_ = vector&lt;vector&lt;vector&lt;int&gt;&gt;&gt;(N + 1, vector&lt;vector&lt;int&gt;&gt;(m, vector&lt;int&gt;(n, INT_MIN)));    
    return paths(N, j, i);    
  }
private:
  vector&lt;vector&lt;vector&lt;int&gt;&gt;&gt; dp_;
  int m_;
  int n_;
  
  // number of paths starts from out-of-boundary to (x, y) by moving at most N steps.
  int paths(int N, int x, int y) {
    static vector&lt;int&gt; dirs{-1, 0, 1, 0, -1};
    static const int kMod = 1000000007;
    // Out of boundary, one path.
    if (x &lt; 0 || x &gt;= n_ || y &lt; 0 || y &gt;= m_) return 1;
    // Can not move but still in the grid, no path.
    if (N == 0) return 0;
    // Already computed.
    if (dp_[N][y][x] != INT_MIN) return dp_[N][y][x];
    
    dp_[N][y][x] = 0;
    
    for (int d = 0; d &lt; 4; ++d) {
      int tx = x + dirs[d];
      int ty = y + dirs[d + 1];
      dp_[N][y][x] = (dp_[N][y][x] + paths(N - 1, tx, ty)) % kMod;
    }        
    
    return dp_[N][y][x];
  }
};</pre><p>no loops</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 4 ms
class Solution {
public:
  int findPaths(int m, int n, int N, int i, int j) {    
    m_ = m;
    n_ = n;
    dp_ = vector&lt;vector&lt;vector&lt;int&gt;&gt;&gt;(N + 1, vector&lt;vector&lt;int&gt;&gt;(m, vector&lt;int&gt;(n, INT_MIN)));    
    return paths(N, j, i);    
  }
private:
  vector&lt;vector&lt;vector&lt;int&gt;&gt;&gt; dp_;
  int m_;
  int n_;
  
  // number of paths start from (x, y) and move at most N steps.
  int paths(int N, int x, int y) {    
    static const int kMod = 1000000007;
    
    if (x &lt; 0 || x &gt;= n_ || y &lt; 0 || y &gt;= m_) return 1;
    if (N == 0) return 0;
    if (dp_[N][y][x] != INT_MIN) return dp_[N][y][x];
    
    long ans = 0;
    ans += paths(N - 1, x + 1, y);
    ans += paths(N - 1, x - 1, y);
    ans += paths(N - 1, x, y + 1);
    ans += paths(N - 1, x, y - 1);
    ans %= kMod;
    
    return dp_[N][y][x] = ans;
  }
};</pre><p>&nbsp;</p>
<h1><strong>Related Problems</strong></h1>
<ul>
<li><a href="http://zxi.mytechroad.com/blog/dynamic-programming/leetcode-62-unique-paths/">花花酱 LeetCode 62. Unique Paths</a></li>
<li><a href="http://zxi.mytechroad.com/blog/dynamic-programming/leetcode-63-unique-paths-ii/">花花酱 LeetCode 63. Unique Paths II</a></li>
<li><a href="http://zxi.mytechroad.com/blog/dynamic-programming/688-knight-probability-in-chessboard/">花花酱 688. Knight Probability in Chessboard</a></li>
</ul>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-576-out-of-boundary-paths/">花花酱 LeetCode 576. Out of Boundary Paths</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-576-out-of-boundary-paths/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 329. Longest Increasing Path in a Matrix</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-329-longest-increasing-path-in-a-matrix/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-329-longest-increasing-path-in-a-matrix/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Fri, 25 May 2018 04:55:24 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[path]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=2839</guid>

					<description><![CDATA[<p>Problem Given an integer matrix, find the length of the longest increasing path. From each cell, you can either move to four directions: left, right,&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-329-longest-increasing-path-in-a-matrix/">花花酱 LeetCode 329. Longest Increasing Path 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><iframe width="500" height="375" src="https://www.youtube.com/embed/yKr4iyQnBpY?feature=oembed" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></p>
<h1><strong>Problem</strong></h1>
<p>Given an integer matrix, find the length of the longest increasing path.</p>
<p>From each cell, you can either move to four directions: left, right, up or down. You may NOT move diagonally or move outside of the boundary (i.e. wrap-around is not allowed).</p>
<p><b>Example 1:</b></p>
<pre class="crayon:false"><strong>Input: </strong>nums = 
[
  [<span style="color: red;">9</span>,9,4],
  [<span style="color: red;">6</span>,6,8],
  [<span style="color: red;">2</span>,<span style="color: red;">1</span>,1]
] 
<strong>Output:</strong> 4 
<strong>Explanation:</strong> The longest increasing path is <code>[1, 2, 6, 9]</code>.</pre>
<p><b>Example 2:</b></p>
<pre class="crayon:false"><strong>Input:</strong> nums = 
[
  [<span style="color: red;">3</span>,<span style="color: red;">4</span>,<span style="color: red;">5</span>],
  [3,2,<span style="color: red;">6</span>],
  [2,2,1]
] 
<strong>Output: </strong>4 
<strong>Explanation: </strong>The longest increasing path is <code>[3, 4, 5, 6]</code>. Moving diagonally is not allowed.</pre>
<h1><img class="alignnone size-full wp-image-2845" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2018/05/329-ep189.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/05/329-ep189.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/05/329-ep189-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/05/329-ep189-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></h1>
<h1><strong>Solution1: DFS + Memorization</strong></h1>
<p>Time complexity: O(mn)</p>
<p>Space complexity: O(mn)</p>
<p>C++</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 36 ms
class Solution {
public:
  int longestIncreasingPath(vector&lt;vector&lt;int&gt;&gt;&amp; matrix) {
    if (matrix.empty()) return 0;
    m_ = matrix.size();
    n_ = matrix[0].size();
    dp_ = vector&lt;vector&lt;int&gt;&gt;(m_, vector&lt;int&gt;(n_, -1)); 
    int ans = 0;
    for (int y = 0; y &lt; m_; ++y)
      for (int x = 0; x &lt; n_; ++x)
        ans = max(ans, dfs(matrix, x, y));
    return ans;
  }
private:
  int dfs(const vector&lt;vector&lt;int&gt;&gt;&amp; mat, int x, int y) {
    if (dp_[y][x] != -1) return dp_[y][x];
    static int dirs[] = {0, -1, 0, 1, 0};
    dp_[y][x] = 1;
    for (int i = 0; i &lt; 4; ++i) {
      int tx = x + dirs[i];
      int ty = y + dirs[i + 1];
      if (tx &lt; 0 || ty &lt; 0 || tx &gt;= n_ || ty &gt;= m_ || mat[ty][tx] &lt;= mat[y][x]) 
        continue;
      dp_[y][x] = max(dp_[y][x], 1 + dfs(mat, tx, ty));
    }
    return dp_[y][x];
  }
  
  int m_;
  int n_;
  // dp[i][j]: max length start from (j, i)
  vector&lt;vector&lt;int&gt;&gt; dp_;  
};</pre><p></p>
<h1><strong>Solution2: DP</strong></h1>
<p>DP</p>
<p>Time complexity: O(mn*log(mn))</p>
<p>Space complexity: O(mn)</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 63 ms
class Solution {
public:
  int longestIncreasingPath(vector&lt;vector&lt;int&gt;&gt;&amp; matrix) {
    if (matrix.empty()) return 0;
    int m = matrix.size();
    int n = matrix[0].size();
    vector&lt;vector&lt;int&gt;&gt; dp(m, vector&lt;int&gt;(n, 1)); 
    int ans = 0;
    
    vector&lt;pair&lt;int, pair&lt;int, int&gt;&gt;&gt; cells;
    for (int y = 0; y &lt; m; ++y)
      for (int x = 0; x &lt; n; ++x)
        cells.push_back({matrix[y][x], {x, y}});
    sort(cells.rbegin(), cells.rend());
    
    vector&lt;int&gt; dirs {0, 1, 0, -1, 0};    
    for (const auto&amp; cell : cells) {
      int x = cell.second.first;
      int y = cell.second.second;
      for (int i = 0; i &lt; 4; ++i) {
        int tx = x + dirs[i];
        int ty = y + dirs[i + 1];
        if (tx &lt; 0 || tx &gt;= n || ty &lt; 0 || ty &gt;= m) continue;
        if (matrix[ty][tx] &lt;= matrix[y][x]) continue;
        dp[y][x] = max(dp[y][x], 1 + dp[ty][tx]);            
      }
      ans = max(ans, dp[y][x]);
    }
    return ans;
  }
};</pre><p>&nbsp;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-329-longest-increasing-path-in-a-matrix/">花花酱 LeetCode 329. Longest Increasing Path 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/dynamic-programming/leetcode-329-longest-increasing-path-in-a-matrix/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 609. Find Duplicate File in System</title>
		<link>https://zxi.mytechroad.com/blog/string/leetcode-609-find-duplicate-file-in-system/</link>
					<comments>https://zxi.mytechroad.com/blog/string/leetcode-609-find-duplicate-file-in-system/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Wed, 21 Mar 2018 04:21:35 +0000</pubDate>
				<category><![CDATA[Hashtable]]></category>
		<category><![CDATA[String]]></category>
		<category><![CDATA[file]]></category>
		<category><![CDATA[hashtable]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[path]]></category>
		<category><![CDATA[string]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=2258</guid>

					<description><![CDATA[<p>Problem https://leetcode.com/problems/find-duplicate-file-in-system/description/ 题目大意：输出系统中文件内容相同的文件名。 Given a list of directory info including directory path, and all the files with contents in this directory, you need to find&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/string/leetcode-609-find-duplicate-file-in-system/">花花酱 LeetCode 609. Find Duplicate File in System</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><a href="https://leetcode.com/problems/find-duplicate-file-in-system/description/">https://leetcode.com/problems/find-duplicate-file-in-system/description/</a></p>
<p>题目大意：输出系统中文件内容相同的文件名。</p>
<p>Given a list of directory info including directory path, and all the files with contents in this directory, you need to find out all the groups of duplicate files in the file system in terms of their paths.</p>
<p>A group of duplicate files consists of at least <b>two</b> files that have exactly the same content.</p>
<p>A single directory info string in the <b>input</b> list has the following format:</p>
<p><code>"root/d1/d2/.../dm f1.txt(f1_content) f2.txt(f2_content) ... fn.txt(fn_content)"</code></p>
<p>It means there are <b>n</b> files (<code>f1.txt</code>, <code>f2.txt</code> &#8230; <code>fn.txt</code> with content <code>f1_content</code>, <code>f2_content</code> &#8230; <code>fn_content</code>, respectively) in directory <code>root/d1/d2/.../dm</code>. Note that n &gt;= 1 and m &gt;= 0. If m = 0, it means the directory is just the root directory.</p>
<p>The <b>output</b> is a list of group of duplicate file paths. For each group, it contains all the file paths of the files that have the same content. A file path is a string that has the following format:</p>
<p><code>"directory_path/file_name.txt"</code></p>
<p><b>Example 1:</b></p>
<pre class="crayon:false "><b>Input:</b>
["root/a 1.txt(abcd) 2.txt(efgh)", "root/c 3.txt(abcd)", "root/c/d 4.txt(efgh)", "root 4.txt(efgh)"]
<b>Output:</b>  
[["root/a/2.txt","root/c/d/4.txt","root/4.txt"],["root/a/1.txt","root/c/3.txt"]]
</pre>
<p><b>Note:</b></p>
<ol>
<li>No order is required for the final output.</li>
<li>You may assume the directory name, file name and file content only has letters and digits, and the length of file content is in the range of [1,50].</li>
<li>The number of files given is in the range of [1,20000].</li>
<li>You may assume no files or directories share the same name in the same directory.</li>
<li>You may assume each given directory info represents a unique directory. Directory path and file info are separated by a single blank space.</li>
</ol>
<h1><b>Follow-up beyond contest:</b></h1>
<ol>
<li>Imagine you are given a real file system, how will you search files? DFS or BFS?</li>
<li>If the file content is very large (GB level), how will you modify your solution?</li>
<li>If you can only read the file by 1kb each time, how will you modify your solution?</li>
<li>What is the time complexity of your modified solution? What is the most time-consuming part and memory consuming part of it? How to optimize?</li>
<li>How to make sure the duplicated files you find are not false positive?</li>
</ol>
<h1><strong>Solution: HashTable</strong></h1>
<p>Key: content, Value: Array of filenames</p>
<p>Time complexity: O(n)</p>
<p>Space complexity: O(n)</p>
<p>C++</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 80ms (beats 94.68%)
class Solution {
public:
  vector&lt;vector&lt;string&gt;&gt; findDuplicate(vector&lt;string&gt;&amp; paths) {
    unordered_map&lt;string, vector&lt;string&gt;&gt; files; // content -&gt; filenames
    for (const string&amp; path : paths) {
      string folder;
      int i = 0;
      while (path[i] != ' ') folder += path[i++]; 
      while (i &lt; path.length()) {
        string filename;
        string content;
        ++i; // ' '
        while (path[i] != '(') filename += path[i++];
        ++i; // '('
        while (path[i] != ')') content += path[i++];
        ++i; // ')'        
        files[content].push_back(folder + "/" + filename);
      }      
    }
    vector&lt;vector&lt;string&gt;&gt; ans;
    for (auto&amp; kv : files) 
      if (kv.second.size() &gt; 1)
        ans.push_back(std::move(kv.second));      
    return ans;
  }
};</pre><p>&nbsp;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/string/leetcode-609-find-duplicate-file-in-system/">花花酱 LeetCode 609. Find Duplicate File in System</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/string/leetcode-609-find-duplicate-file-in-system/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 687. Longest Univalue Path</title>
		<link>https://zxi.mytechroad.com/blog/tree/leetcode-687-longest-univalue-path/</link>
					<comments>https://zxi.mytechroad.com/blog/tree/leetcode-687-longest-univalue-path/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 01 Oct 2017 16:42:45 +0000</pubDate>
				<category><![CDATA[Tree]]></category>
		<category><![CDATA[longest]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[path]]></category>
		<category><![CDATA[recursion]]></category>
		<category><![CDATA[tree]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=489</guid>

					<description><![CDATA[<p>题目大意：给你一棵二叉树，返回一条最长的路径，要求路径上所有的节点值都相同。 https://leetcode.com/problems/longest-univalue-path/description/ Problem:  Given a binary tree, find the length of the longest path where each node in the path has the same value. This&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/tree/leetcode-687-longest-univalue-path/">花花酱 LeetCode 687. Longest Univalue Path</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/yX1hVhcHcH8?feature=oembed" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></p>
<p>题目大意：给你一棵二叉树，返回一条最长的路径，要求路径上所有的节点值都相同。</p>
<p><a href="https://leetcode.com/problems/longest-univalue-path/description/">https://leetcode.com/problems/longest-univalue-path/description/</a></p>
<p><strong>Problem: </strong></p>
<p>Given a binary tree, find the length of the longest path where each node in the path has the same value. This path may or may not pass through the root.</p>
<p><b>Note:</b> The length of path between two nodes is represented by the number of edges between them.</p>
<p><b>Example 1:</b></p>
<p>Input:</p>
<pre class="crayon:false">              5
             / \
            4   5
           / \   \
          1   1   5
</pre>
<p>Output:</p>
<pre class="crayon:false">2
</pre>
<p><b>Example 2:</b></p>
<p>Input:</p>
<pre class="crayon:false">              1
             / \
            4   5
           / \   \
          4   4   5
</pre>
<p>Output:</p>
<pre class="crayon:false">2
</pre>
<p><b>Note:</b> The given binary tree has not more than 10000 nodes. The height of the tree is not more than 1000.</p>
<p><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script><br />
<ins class="adsbygoogle" style="display: block; text-align: center;" data-ad-layout="in-article" data-ad-format="fluid" data-ad-client="ca-pub-2404451723245401" data-ad-slot="7983117522"></ins><br />
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></p>
<p><strong>Idea:</strong></p>
<p>DFS</p>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/687-ep78-1.png"><img class="alignnone size-full wp-image-494" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/687-ep78-1.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/687-ep78-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/687-ep78-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/687-ep78-1-768x432.png 768w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/687-ep78-1-624x351.png 624w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<h1><strong>Solution: Recursion</strong></h1>
<p>Time complexity: O(n)</p>
<p>Space complexity: O(n)</p>
<p><div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 69 ms
class Solution {
public:
    int longestUnivaluePath(TreeNode* root) {
        if (root == nullptr) return 0;
        int ans = 0;
        univaluePath(root, &amp;ans);
        return ans;
    }
private:
    int univaluePath(TreeNode* root, int* ans) {
        if (root == nullptr) return 0;
        int l = univaluePath(root-&gt;left, ans);
        int r = univaluePath(root-&gt;right, ans);
        int pl = 0;
        int pr = 0;
        if (root-&gt;left &amp;&amp; root-&gt;val == root-&gt;left-&gt;val) pl = l + 1;
        if (root-&gt;right &amp;&amp; root-&gt;val == root-&gt;right-&gt;val) pr = r + 1;
        *ans = max(*ans, pl + pr);
        return max(pl, pr);
    }
};</pre><p></div><h2 class="tabtitle">Java</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 12 ms
class Solution {
    private int ans;
    public int longestUnivaluePath(TreeNode root) {
        if (root == null) return 0;        
        this.ans = 0;
        univaluePath(root);
        return this.ans;
    }
    
    private int univaluePath(TreeNode root) {
        if (root == null) return 0;
        int l = univaluePath(root.left);
        int r = univaluePath(root.right);
        int pl = 0;
        int pr = 0;
        if (root.left != null &amp;&amp; root.val == root.left.val) pl = l + 1;
        if (root.right != null &amp;&amp; root.val == root.right.val) pr = r + 1;
        this.ans = Math.max(this.ans, pl + pr);
        return Math.max(pl, pr);
    }
}</pre><p></div><h2 class="tabtitle">Python3</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">"""
Author: Huahua
Runtime: 899 ms
"""
class Solution:
    def longestUnivaluePath(self, root):
        self.ans = 0
        self._univaluePath(root)
        return self.ans
    
    def _univaluePath(self, root):
        if root is None: return 0
        l = self._univaluePath(root.left) if root.left is not None else -1
        r = self._univaluePath(root.right) if root.right is not None else -1
        pl = l + 1 if l &gt;= 0 and root.val == root.left.val else 0
        pr = r + 1 if r &gt;= 0 and root.val == root.right.val else 0
        self.ans = max(self.ans, pl + pr)
        return max(pl, pr)</pre><p></div></div></p>
<h1><strong>Related Problems</strong></h1>
<ul>
<li><a href="http://zxi.mytechroad.com/blog/tree/leetcode-124-binary-tree-maximum-path-sum/">花花酱 LeetCode 124. Binary Tree Maximum Path Sum</a></li>
</ul>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/tree/leetcode-687-longest-univalue-path/">花花酱 LeetCode 687. Longest Univalue Path</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/tree/leetcode-687-longest-univalue-path/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
