<?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>Medium Archives - Huahua&#039;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/category/difficulty/medium/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog/category/difficulty/medium/</link>
	<description></description>
	<lastBuildDate>Wed, 08 May 2019 03:42:49 +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>Medium Archives - Huahua&#039;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog/category/difficulty/medium/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>花花酱 LeetCode 769. Max Chunks To Make Sorted</title>
		<link>https://zxi.mytechroad.com/blog/difficulty/medium/leetcode-769-max-chunks-to-make-sorted/</link>
					<comments>https://zxi.mytechroad.com/blog/difficulty/medium/leetcode-769-max-chunks-to-make-sorted/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 03 Feb 2018 04:55:32 +0000</pubDate>
				<category><![CDATA[Array]]></category>
		<category><![CDATA[Medium]]></category>
		<category><![CDATA[permutation]]></category>
		<category><![CDATA[sorting]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=1737</guid>

					<description><![CDATA[<p>题目大意：给你一个0 ~ n-1的排列，问你最多能分成几组，每组分别排序后能够组成0 ~ n-1。 Given an array arr that is a permutation of [0, 1, ..., arr.length - 1], we split the array into some number of&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/difficulty/medium/leetcode-769-max-chunks-to-make-sorted/">花花酱 LeetCode 769. Max Chunks To Make Sorted</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/twYLu4hEKnQ?feature=oembed" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></p>
<p>题目大意：给你一个0 ~ n-1的排列，问你最多能分成几组，每组分别排序后能够组成0 ~ n-1。</p>
<p>Given an array <code>arr</code> that is a permutation of <code>[0, 1, ..., arr.length - 1]</code>, we split the array into some number of &#8220;chunks&#8221; (partitions), and individually sort each chunk.  After concatenating them, the result equals the sorted array.</p>
<p>What is the most number of chunks we could have made?</p>
<p><strong>Example 1:</strong></p><pre class="crayon-plain-tag">Input: arr = [4,3,2,1,0]
Output: 1
Explanation:
Splitting into two or more chunks will not return the required result.
For example, splitting into [4, 3], [2, 1, 0] will result in [3, 4, 0, 1, 2], which isn't sorted.</pre><p><strong>Example 2:</strong></p><pre class="crayon-plain-tag">Input: arr = [1,0,2,3,4]
Output: 4
Explanation:
We can split into two chunks, such as [1, 0], [2, 3, 4].
However, splitting into [1, 0], [2], [3], [4] is the highest number of chunks possible.</pre><p><strong>Note:</strong></p>
<ul>
<li><code>arr</code> will have length in range <code>[1, 10]</code>.</li>
<li><code>arr[i]</code> will be a permutation of <code>[0, 1, ..., arr.length - 1]</code>.</li>
</ul>
<p><strong>Solution 1: Max so far / Set</strong></p>
<p>Time complexity: O(nlogn)</p>
<p>Space complexity: O(n)</p>
<p>C++</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 3 ms
class Solution {
public:
  int maxChunksToSorted(vector&lt;int&gt;&amp; arr) {
    int ans = 0;
    set&lt;int&gt; s;
    for (int i = 0; i &lt; arr.size(); ++i) {
      s.insert(arr[i]);
      if (*s.rbegin() == i) ++ans;
    }
    return ans;
  }
};</pre><p>&nbsp;</p>
<p><strong>Solution 2: Max so far</strong></p>
<p>Time complexity: O(n)</p>
<p>Space complexity: O(1)</p>
<p>C++</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 4 ms
class Solution {
public:
  int maxChunksToSorted(vector&lt;int&gt;&amp; arr) {
    int ans = 0;
    int m = 0;
    for (int i = 0; i &lt; arr.size(); ++i) {
      m = max(m, arr[i]);
      if (m == i) ++ans;
    }
    return ans;
  }
};</pre><p>Java</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 5 ms
class Solution {
  public int maxChunksToSorted(int[] arr) {
    int max = 0;
    int ans = 0;
    for (int i = 0; i &lt; arr.length; ++i) {
      max = Math.max(max, arr[i]);
      if (max == i) ++ans;
    }
    return ans;
  }
}</pre><p>Python3</p><pre class="crayon-plain-tag">"""
Author: Huahua
Running time: 53 ms
"""
class Solution:
  def maxChunksToSorted(self, arr):
    m = 0
    ans = 0
    for i, n in enumerate(arr):
      if n &gt; m: m = n
      if m == i: ans += 1
    return ans</pre><p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/difficulty/medium/leetcode-769-max-chunks-to-make-sorted/">花花酱 LeetCode 769. Max Chunks To Make Sorted</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/difficulty/medium/leetcode-769-max-chunks-to-make-sorted/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 763. Partition Labels</title>
		<link>https://zxi.mytechroad.com/blog/string/leetcode-763-partition-labels/</link>
					<comments>https://zxi.mytechroad.com/blog/string/leetcode-763-partition-labels/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Fri, 26 Jan 2018 06:08:15 +0000</pubDate>
				<category><![CDATA[Greedy]]></category>
		<category><![CDATA[Medium]]></category>
		<category><![CDATA[String]]></category>
		<category><![CDATA[greedy]]></category>
		<category><![CDATA[partition]]></category>
		<category><![CDATA[string]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=1665</guid>

					<description><![CDATA[<p>题目大意：把字符串分割成尽量多的不重叠子串，输出子串的长度数组。要求相同字符只能出现在一个子串中。 Problem: A string S of lowercase letters is given. We want to partition this string into as many parts as possible so that each letter appears&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/string/leetcode-763-partition-labels/">花花酱 LeetCode 763. Partition Labels</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/s-1W5FDJ0lw?feature=oembed" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></p>
<p>题目大意：把字符串分割成尽量多的不重叠子串，输出子串的长度数组。要求相同字符只能出现在一个子串中。</p>
<p><strong>Problem:</strong></p>
<p>A string <code>S</code> of lowercase letters is given. We want to partition this string into as many parts as possible so that each letter appears in at most one part, and return a list of integers representing the size of these parts.</p>
<p><b>Example 1:</b></p><pre class="crayon-plain-tag">Input: S = &quot;ababcbacadefegdehijhklij&quot;
Output: [9,7,8]
Explanation:
The partition is &quot;ababcbaca&quot;, &quot;defegde&quot;, &quot;hijhklij&quot;.
This is a partition so that each letter appears in at most one part.
A partition like &quot;ababcbacadefegde&quot;, &quot;hijhklij&quot; is incorrect, because it splits S into less parts.</pre><p><img class="alignnone size-full wp-image-1680" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/763-ep161.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/763-ep161.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/763-ep161-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/763-ep161-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p><strong>Solution 0: Brute Force</strong></p>
<p>Time complexity: O(n^2)</p>
<p>Space complexity: O(1)</p>
<p>C++</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 15 ms
class Solution {
public:
    vector&lt;int&gt; partitionLabels(string S) {
      vector&lt;int&gt; ans;
      size_t start = 0;
      size_t end = 0;
      for (size_t i = 0; i &lt; S.size(); ++i) {
        end = max(end, S.find_last_of(S[i]));
        if (i == end) {
          ans.push_back(end - start + 1);
          start = end + 1;
        }
      }
      return ans;
    }
};</pre><p>Python</p><pre class="crayon-plain-tag">"""
Author: Huahua
Running time : 48 ms
"""
class Solution:
  def partitionLabels(self, S):
    ans = []
    start, end = 0, 0
    for i in range(len(S)):
      end = max(end, S.rfind(S[i]))
      if i == end:
        ans.append(end - start + 1)
        start = end + 1
    return ans</pre><p>&nbsp;</p>
<p><strong>Solution 1: Greedy </strong></p>
<p>Time complexity: O(n)</p>
<p>Space complexity: O(26/128)</p>
<p>C++</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 6 ms
class Solution {
public:
    vector&lt;int&gt; partitionLabels(string S) {
      vector&lt;int&gt; last_index(128, 0);
      for (int i = 0; i &lt; S.size(); ++i)
        last_index[S[i]] = i;
      vector&lt;int&gt; ans;
      int start = 0;
      int end = 0;
      for (int i = 0; i &lt; S.size(); ++i) {
        end = max(end, last_index[S[i]]);
        if (i == end) {
          ans.push_back(end - start + 1);
          start = end + 1;
        }
      }
      return ans;
    }
};</pre><p>Java</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 16 ms
class Solution {
  public List&lt;Integer&gt; partitionLabels(String S) {
    int lastIndex[] = new int[128];
    for (int i = 0; i &lt; S.length(); ++i)
      lastIndex[(int)S.charAt(i)] = i;
    List&lt;Integer&gt; ans = new ArrayList&lt;&gt;();
    int start = 0;
    int end = 0;
    for (int i = 0; i &lt; S.length(); ++i) {
      end = Math.max(end, lastIndex[(int)S.charAt(i)]);
      if (i == end) {
        ans.add(end - start + 1);
        start = end + 1;
      }
    }
    return ans;
  }
}</pre><p>Python3</p><pre class="crayon-plain-tag">"""
Author: Huahua
Running time: 78 ms
"""
class Solution:
  def partitionLabels(self, S):
    last_index = {}
    for i, ch in enumerate(S):
      last_index[ch] = i
    start = end = 0
    ans = []
    for i, ch in enumerate(S):
      end = max(end, last_index[ch])
      if i == end:
        ans.append(end - start + 1)
        start = end + 1
    return ans</pre><p>&nbsp;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/string/leetcode-763-partition-labels/">花花酱 LeetCode 763. Partition Labels</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-763-partition-labels/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 494. Target Sum</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-494-target-sum/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-494-target-sum/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Wed, 10 Jan 2018 06:13:49 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[Medium]]></category>
		<category><![CDATA[combination]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[sum]]></category>
		<category><![CDATA[target]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=1587</guid>

					<description><![CDATA[<p>题目大意：给你一串数字，你可以在每个数字前放置+或-，问有多少种方法可以使得表达式的值等于target。You are given a list of non-negative integers, a1, a2, &#8230;, an, and a target, S. Now you have 2 symbols + and -. For each integer, you&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-494-target-sum/">花花酱 LeetCode 494. Target 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><iframe width="500" height="375" src="https://www.youtube.com/embed/r6Wz4W1TbuI?feature=oembed" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></p>
<p><iframe width="500" height="375" src="https://www.youtube.com/embed/zks6mN06xdQ?feature=oembed" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></p>
<p>题目大意：给你一串数字，你可以在每个数字前放置+或-，问有多少种方法可以使得表达式的值等于target。You are given a list of non-negative integers, a1, a2, &#8230;, an, and a target, S. Now you have 2 symbols <code>+</code> and <code>-</code>. For each integer, you should choose one from <code>+</code> and <code>-</code> as its new symbol.</p>
<p>Find out how many ways to assign symbols to make sum of integers equal to target S.</p>
<p><b>Example 1:</b></p><pre class="crayon-plain-tag">Input: nums is [1, 1, 1, 1, 1], S is 3. 
Output: 5
Explanation: 

-1+1+1+1+1 = 3
+1-1+1+1+1 = 3
+1+1-1+1+1 = 3
+1+1+1-1+1 = 3
+1+1+1+1-1 = 3

There are 5 ways to assign symbols to make the sum of nums be target 3.</pre><p><b>Note:</b></p>
<ol>
<li>The length of the given array is positive and will not exceed 20.</li>
<li>The sum of elements in the given array will not exceed 1000.</li>
<li>Your output answer is guaranteed to be fitted in a 32-bit integer.</li>
</ol>
<p><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></p>
<h1><strong>Idea: DP</strong></h1>
<p><img class="alignnone size-full wp-image-1598" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/494-ep156-2.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/494-ep156-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/494-ep156-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/494-ep156-2-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p><img class="alignnone size-full wp-image-1599" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/494-ep156-1.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/494-ep156-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/494-ep156-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/494-ep156-1-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p><img class="alignnone size-full wp-image-1597" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/494-ep156-3.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/494-ep156-3.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/494-ep156-3-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/494-ep156-3-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p><img class="alignnone size-full wp-image-1609" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/494-ep156-4.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/494-ep156-4.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/494-ep156-4-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/494-ep156-4-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p><img class="alignnone size-full wp-image-1608" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/494-ep156-5.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/494-ep156-5.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/494-ep156-5-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/494-ep156-5-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p><img class="alignnone size-full wp-image-1607" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/494-ep156-6.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/494-ep156-6.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/494-ep156-6-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/494-ep156-6-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p><img class="alignnone size-full wp-image-1606" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/494-ep156-7.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/494-ep156-7.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/494-ep156-7-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/494-ep156-7-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p><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"><br />
</ins></p>
<h1><strong>Solution 1: DP</strong></h1>
<p>Time complexity: O(n*sum)</p>
<p>Space complexity: O(n*sum)</p>
<p><div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 16 ms
class Solution {
public:
    int findTargetSumWays(vector&lt;int&gt;&amp; nums, int S) {
      const int n = nums.size();
      const int sum = std::accumulate(nums.begin(), nums.end(), 0);
      if (sum &lt; S) return 0;
      const int offset = sum;
      // ways[i][j] means total ways to sum up to (j - offset) using nums[0] ~ nums[i - 1].
      vector&lt;vector&lt;int&gt;&gt; ways(n + 1, vector&lt;int&gt;(sum + offset + 1, 0));
      ways[0][offset] = 1;
      for (int i = 0; i &lt; n; ++i) {
        for (int j = nums[i]; j &lt; 2 * sum + 1 - nums[i]; ++j)
          if (ways[i][j]) {
            ways[i + 1][j + nums[i]] += ways[i][j];
            ways[i + 1][j - nums[i]] += ways[i][j];
          }        
      }
      
      return ways.back()[S + offset];
    }
};</pre><p></div><h2 class="tabtitle">C++ SC O(n)</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 12 ms
class Solution {
public:
    int findTargetSumWays(vector&lt;int&gt;&amp; nums, int S) {
      const int n = nums.size();
      const int sum = std::accumulate(nums.begin(), nums.end(), 0);
      if (sum &lt; std::abs(S)) return 0;
      const int kOffset = sum;
      const int kMaxN = sum * 2 + 1;
      vector&lt;int&gt; ways(kMaxN, 0);      
      ways[kOffset] = 1;
      for (int num : nums) {
        vector&lt;int&gt; tmp(kMaxN, 0);
        for (int i = num; i &lt; kMaxN - num; ++i)
          if (ways[i]) {
            tmp[i + num] += ways[i];
            tmp[i - num] += ways[i];
          }
        std::swap(ways, tmp);
      }      
      return ways[S + kOffset];
    }
};</pre><p></div><h2 class="tabtitle">Java</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 28 ms
class Solution {
  public int findTargetSumWays(int[] nums, int S) {
    int sum = 0;
    for (final int num : nums)
      sum += num;
    if (sum &lt; S) return 0;
    final int kOffset = sum;
    final int kMaxN = sum * 2 + 1;
    int[] ways = new int[kMaxN];
    ways[kOffset] = 1;
    for (final int num : nums) {      
      int[] tmp = new int[kMaxN];      
      for (int i = num; i &lt; kMaxN - num; ++i) {
        tmp[i + num] += ways[i];
        tmp[i - num] += ways[i];
      }
      ways = tmp;
    }
    return ways[S + kOffset];
  }
}</pre><p></div><h2 class="tabtitle">C++ / V2</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 17 ms
class Solution {
public:
    int findTargetSumWays(vector&lt;int&gt;&amp; nums, int S) {
      const int n = nums.size();
      const int sum = std::accumulate(nums.begin(), nums.end(), 0);
      if (sum &lt; std::abs(S)) return 0;
      const int kOffset = sum;
      const int kMaxN = sum * 2 + 1;
      vector&lt;int&gt; ways(kMaxN, 0);      
      ways[kOffset] = 1;
      for (int num : nums) {
        vector&lt;int&gt; tmp(kMaxN, 0);
        for (int i = 0; i &lt; kMaxN; ++i) {
          if (i + num &lt; kMaxN) tmp[i] += ways[i + num];
          if (i - num &gt;= 0)    tmp[i] += ways[i - num];
        }
        std::swap(ways, tmp);
      }
      return ways[S + kOffset];
    }
};</pre><p></div></div></p>
<h1><strong>Solution 2: DFS</strong></h1>
<p>Time complexity: O(2^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
// Running time: 422 ms
class Solution {
public:
  int findTargetSumWays(vector&lt;int&gt;&amp; nums, int S) {
    const int sum = std::accumulate(nums.begin(), nums.end(), 0);
    if (sum &lt; std::abs(S)) return 0;
    int ans = 0;
    dfs(nums, 0, S, ans);
    return ans;
  }
private:
  void dfs(const vector&lt;int&gt;&amp; nums, int d, int S, int&amp; ans) {
    if (d == nums.size()) {
      if (S == 0) ++ans;
      return;
    }    
    dfs(nums, d + 1, S - nums[d], ans);
    dfs(nums, d + 1, S + nums[d], ans);
  }
};</pre><p></div><h2 class="tabtitle">Java</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 615 ms
class Solution {
  private int ans;
  public int findTargetSumWays(int[] nums, int S) {
    int sum = 0;
    for (final int num : nums)
      sum += num;
    if (sum &lt; Math.abs(S)) return 0;
    ans = 0;
    dfs(nums, 0, S);
    return ans;
  }
  
  private void dfs(int[] nums, int d, int S) {
    if (d == nums.length) {
      if (S == 0) ++ans;
      return;
    }
    dfs(nums, d + 1, S - nums[d]);
    dfs(nums, d + 1, S + nums[d]);
  }
}</pre><p></div></div></p>
<h1><strong>Solution 3: Subset sum</strong></h1>
<p>Time complexity: O(n*sum)</p>
<p>Space complexity: O(sum)</p>
<p><div class="responsive-tabs">
<h2 class="tabtitle">C++ w/ copy</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 7 ms
class Solution {
public:
    int findTargetSumWays(vector&lt;int&gt;&amp; nums, int S) {
      S = std::abs(S);      
      const int sum = std::accumulate(nums.begin(), nums.end(), 0);
      if (sum &lt; S || (S + sum) % 2 != 0) return 0;
      const int target = (S + sum) / 2;
      vector&lt;int&gt; dp(target + 1, 0);
      dp[0] = 1;
      for (int num : nums) {
        vector&lt;int&gt; tmp(dp);
        for (int j = 0; j &lt;= target - num; ++j)
          tmp[j + num] += dp[j];
        std::swap(dp, tmp);
      }
      
      return dp[target];
    }
};</pre><p></div><h2 class="tabtitle">C++  w/o copy</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 6 ms
class Solution {
public:
    int findTargetSumWays(vector&lt;int&gt;&amp; nums, int S) {
      S = std::abs(S);
      const int n = nums.size();
      const int sum = std::accumulate(nums.begin(), nums.end(), 0);
      if (sum &lt; S || (S + sum) % 2 != 0) return 0;
      const int target = (S + sum) / 2;
      vector&lt;int&gt; dp(target + 1, 0);
      dp[0] = 1;
      for (int num : nums)
        for (int j = target; j &gt;= num; --j)
          dp[j] += dp[j - num];
      
      return dp[target];
    }
};</pre><p></div></div></p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-494-target-sum/">花花酱 LeetCode 494. Target 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-494-target-sum/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 322. Coin Change</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-322-coin-change/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-322-coin-change/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Wed, 03 Jan 2018 03:50:16 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[Medium]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[knapsack]]></category>
		<category><![CDATA[medium]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=1469</guid>

					<description><![CDATA[<p>题目大意：给你一些不同币值的硬币，问你最少需要多少个硬币才能组成amount，假设每种硬币有无穷多个。 Problem: You are given coins of different denominations and a total amount of money amount. Write a function to compute the fewest number of coins&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-322-coin-change/">花花酱 LeetCode 322. Coin Change</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/uUETHdijzkA?feature=oembed" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></p>
<p>题目大意：给你一些不同币值的硬币，问你最少需要多少个硬币才能组成amount，假设每种硬币有无穷多个。</p>
<p><strong>Problem:</strong></p>
<p>You are given coins of different denominations and a total amount of money <i>amount</i>. Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return <code>-1</code>.</p>
<p><b>Example 1:</b><br />
coins = <code>[1, 2, 5]</code>, amount = <code>11</code><br />
return <code>3</code> (11 = 5 + 5 + 1)</p>
<p><b>Example 2:</b><br />
coins = <code>[2]</code>, amount = <code>3</code><br />
return <code>-1</code>.</p>
<p><strong>Idea:</strong></p>
<p>DP /knapsack</p>
<p>Search</p>
<p><img class="alignnone wp-image-1479 size-full" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/322-ep148.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/322-ep148.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/322-ep148-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/322-ep148-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p><img class="alignnone size-full wp-image-1477" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/322-ep148-2.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/322-ep148-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/322-ep148-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/322-ep148-2-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p><strong>Solution1:</strong></p>
<p>C++ / DP</p>
<p>Time complexity: O(n*amount^2)</p>
<p>Space complexity: O(amount)</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 189 ms
class Solution {
public:
    int coinChange(vector&lt;int&gt;&amp; coins, int amount) {
        vector&lt;int&gt; dp(amount + 1, INT_MAX);
        dp[0] = 0;
        for (auto coin : coins) {
            for (int i = amount - coin; i &gt;= 0; --i)
                if (dp[i] != INT_MAX)
                    for (int k = 1; k * coin + i &lt;= amount; ++k)
                        dp[i + k * coin] = min(dp[i + k * coin], dp[i] + k);
        }
        
        return dp[amount] == INT_MAX ? -1 : dp[amount];
    }
};</pre><p><strong>Solution2:</strong></p>
<p>C++ / DP</p>
<p>Time complexity: O(n*amount)</p>
<p>Space complexity: O(amount)</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 16 ms
class Solution {
public:
    int coinChange(vector&lt;int&gt;&amp; coins, int amount) {
        // dp[i] = min coins to make up to amount i
        vector&lt;int&gt; dp(amount + 1, INT_MAX);
        dp[0] = 0;
        for (int coin : coins) {
            for (int i = coin; i &lt;= amount; ++i)
                if (dp[i - coin] != INT_MAX)  
                    dp[i] = min(dp[i], dp[i - coin] + 1);
        }
        
        return dp[amount] == INT_MAX ? -1 : dp[amount];
    }
};</pre><p>Python3</p><pre class="crayon-plain-tag">"""
Author: Huahua
Running time: 632 ms beats 90.27%
"""
class Solution:
  def coinChange(self, coins, amount):
    INVALID = 2**32
    dp = [INVALID] * (amount + 1)
    dp[0] = 0
    for coin in coins:
      for i in range(coin, amount + 1):
        if dp[i - coin] &gt;= dp[i]: continue
        dp[i] = dp[i - coin] + 1
    return -1 if dp[amount] == INVALID else dp[amount]</pre><p><strong>Solution3:</strong></p>
<p>C++ / DFS</p>
<p>Time complexity: O(amount^n/(coin_0*coin_1*&#8230;*coin_n))</p>
<p>Space complexity: O(n)</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 6 ms
class Solution {
public:
    int coinChange(vector&lt;int&gt;&amp; coins, int amount) {
        // Sort coins in desending order
        std::sort(coins.rbegin(), coins.rend());
        int ans = INT_MAX;
        coinChange(coins, 0, amount, 0, ans);
        return ans == INT_MAX ? -1 : ans;
    }
private:
    void coinChange(const vector&lt;int&gt;&amp; coins, 
                    int s, int amount, int count, int&amp; ans) {
        if (amount == 0) {
            ans = min(ans, count);
            return;
        }
        
        if (s == coins.size()) return;
        
        const int coin = coins[s];                
        for (int k = amount / coin; k &gt;= 0 &amp;&amp; count + k &lt; ans; k--)
            coinChange(coins, s + 1, amount - k * coin, count + k, ans);
    }    
};</pre><p>Python3</p><pre class="crayon-plain-tag">"""
Author: Huahua
Running time: 200ms
"""
class Solution:
  def coinChange(self, coins, amount):
    coins.sort(reverse=True)
    INVALID = 10**10
    self.ans = INVALID
    def dfs(s, amount, count):      
      if amount == 0:
        self.ans = count
        return
      if s == len(coins): return
      
      coin = coins[s]
      for k in range(amount // coin, -1, -1):
        if count + k &gt;= self.ans: break
        dfs(s + 1, amount - k * coin, count + k)
    dfs(0, amount, 0)
    return -1 if self.ans == INVALID else self.ans</pre><p>&nbsp;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-322-coin-change/">花花酱 LeetCode 322. Coin Change</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-322-coin-change/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 652. Find Duplicate Subtrees</title>
		<link>https://zxi.mytechroad.com/blog/tree/leetcode-652-find-duplicate-subtrees/</link>
					<comments>https://zxi.mytechroad.com/blog/tree/leetcode-652-find-duplicate-subtrees/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 31 Dec 2017 23:18:34 +0000</pubDate>
				<category><![CDATA[Medium]]></category>
		<category><![CDATA[Tree]]></category>
		<category><![CDATA[hash]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[serialization]]></category>
		<category><![CDATA[subtree]]></category>
		<category><![CDATA[tree]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=1390</guid>

					<description><![CDATA[<p>652.&#160;Find Duplicate SubtreesMedium730151FavoriteShare Given a binary tree, return all duplicate subtrees. For each kind of duplicate subtrees, you only need to return the root node&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/tree/leetcode-652-find-duplicate-subtrees/">花花酱 LeetCode 652. Find Duplicate Subtrees</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>

652.&nbsp;Find Duplicate SubtreesMedium730151FavoriteShare</p>



<p>Given a binary tree, return all duplicate subtrees. For each kind of duplicate subtrees, you only need to return the root node of any&nbsp;<strong>one</strong>&nbsp;of them.</p>



<p>Two trees are duplicate if they have the same structure with same node values.</p>



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



<p>The following are two duplicate subtrees:</p>



<pre class="wp-block-preformatted; crayon:false">        1
       / \
      2   3
     /   / \
    4   2   4
       /
      4</pre>



<p>  2<br> /<br>4</p>



<p>and</p>



<p>4</p>



<p>Therefore, you need to return above trees&#8217; root in the form of a list.

</p>



<figure class="wp-block-image"><img src="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/652-ep146-1.png" alt=""/></figure>



<h2><strong>Solution 1: Serialization </strong></h2>



<p>Time complexity: O(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
// Runtime: 29 ms
class Solution {
public:
    vector&lt;TreeNode*&gt; findDuplicateSubtrees(TreeNode* root) {
        unordered_map&lt;string, int&gt; counts;
        vector&lt;TreeNode*&gt; ans;
        serialize(root, counts, ans);
        return ans;
    }
private:
    string serialize(TreeNode* root, unordered_map&lt;string, int&gt;&amp; counts, vector&lt;TreeNode*&gt;&amp; ans) {
        if (!root) return &quot;#&quot;;
        string key = to_string(root-&gt;val) + &quot;,&quot; 
                     + serialize(root-&gt;left, counts, ans) + &quot;,&quot; 
                     + serialize(root-&gt;right, counts, ans);
        if (++counts[key] == 2)
            ans.push_back(root);
        return key;
    }
};</pre>
</div></div>



<p><strong>Solution 2: int id for each unique subtree</strong></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
// Runtime: 8 ms
class Solution {
public:
  vector&lt;TreeNode*&gt; findDuplicateSubtrees(TreeNode* root) {
    unordered_map&lt;long, pair&lt;int,int&gt;&gt; counts;    
    vector&lt;TreeNode*&gt; ans;
    getId(root, counts, ans);
    return ans;
  }
private:
  int getId(TreeNode* root, 
            unordered_map&lt;long, pair&lt;int,int&gt;&gt;&amp; counts,
            vector&lt;TreeNode*&gt;&amp; ans) {
    if (!root) return 0;
    long key = (static_cast&lt;long&gt;(static_cast&lt;unsigned&gt;(root-&gt;val)) &lt;&lt; 32) +
               (getId(root-&gt;left, counts, ans) &lt;&lt; 16) +
                getId(root-&gt;right, counts, ans);    
    auto&amp; p = counts[key];
    if (p.second++ == 0)
      p.first = counts.size();    
    else if (p.second == 2)
      ans.push_back(root);
    return p.first;
  }
};</pre>
</div></div>



<p></p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/tree/leetcode-652-find-duplicate-subtrees/">花花酱 LeetCode 652. Find Duplicate Subtrees</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-652-find-duplicate-subtrees/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 416. Partition Equal Subset Sum</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-416-partition-equal-subset-sum/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-416-partition-equal-subset-sum/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 31 Dec 2017 22:41:36 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[Medium]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[knapsack]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=1381</guid>

					<description><![CDATA[<p>题目大意： 给你一个正整数的数组，问你能否把元素划分成元素和相等的两组。 Problem: Given a non-empty array containing only positive integers, find if the array can be partitioned into two subsets such that the sum of elements in&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-416-partition-equal-subset-sum/">花花酱 LeetCode 416. Partition Equal Subset 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><iframe width="500" height="375" src="https://www.youtube.com/embed/r6I-ikllNDM?feature=oembed" frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen></iframe></p>
<p>题目大意：</p>
<p>给你一个正整数的数组，问你能否把元素划分成元素和相等的两组。</p>
<p><strong>Problem:</strong></p>
<p>Given a <b>non-empty</b> array containing <b>only positive integers</b>, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal.</p>
<p><b>Note:</b></p>
<ol>
<li>Each of the array element will not exceed 100.</li>
<li>The array size will not exceed 200.</li>
</ol>
<p><b>Example 1:</b></p><pre class="crayon-plain-tag">Input: [1, 5, 11, 5]

Output: true

Explanation: The array can be partitioned as [1, 5, 5] and [11].</pre><p><b>Example 2:</b></p><pre class="crayon-plain-tag">Input: [1, 2, 3, 5]

Output: false

Explanation: The array cannot be partitioned into equal sum subsets.</pre><p>&nbsp;</p>
<p><strong>Idea:</strong></p>
<p>DP 动态规划</p>
<p><strong>Solution:</strong></p>
<p>Time complexity: O(n*sum)</p>
<p>Space complexity: O(sum)</p>
<p>C++</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 16 ms
class Solution {
public:
    bool canPartition(vector&lt;int&gt;&amp; nums) {
        const int sum = std::accumulate(nums.begin(), nums.end(), 0);
        if (sum % 2 != 0) return false;
        vector&lt;int&gt; dp(sum + 1, 0);
        dp[0] = 1;
        for (const int num : nums) {
            for (int i = sum; i &gt;= 0; --i)
                if (dp[i]) dp[i + num] = 1;
            if (dp[sum / 2]) return true;
        }
        return false;
    }
};</pre><p>&nbsp;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-416-partition-equal-subset-sum/">花花酱 LeetCode 416. Partition Equal Subset 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-416-partition-equal-subset-sum/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 377. Combination Sum IV</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-377-combination-sum-iv/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-377-combination-sum-iv/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 16 Dec 2017 07:33:12 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[Medium]]></category>
		<category><![CDATA[counting]]></category>
		<category><![CDATA[dp]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=1259</guid>

					<description><![CDATA[<p>Problem: Given an integer array with all positive numbers and no duplicates, find the number of possible combinations that add up to a positive integer&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-377-combination-sum-iv/">花花酱 LeetCode 377. Combination Sum IV</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/niZlmOtG4jM?feature=oembed" frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen></iframe></p>
<p><strong>Problem:</strong></p>
<p>Given an integer array with all positive numbers and no duplicates, find the number of possible combinations that add up to a positive integer target.</p>
<p><b>Example:</b></p><pre class="crayon-plain-tag">nums = [1, 2, 3]
target = 4

The possible combination ways are:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)

Note that different sequences are counted as different combinations.

Therefore the output is 7.</pre><p>题目大意：给你一些数和一个目标值，问使用这些数(每个数可以被使用任意次数)加起来等于目标值的组合（其实是不重复的排列）有多少种。</p>
<p><strong>Idea:</strong></p>
<p>DP</p>
<p><img class="alignnone size-full wp-image-1269" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/377-ep135.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/377-ep135.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/377-ep135-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/377-ep135-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p><strong>Solution:</strong></p>
<p>C++ / Recursion + Memorization</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 0 ms
class Solution {
public:
    int combinationSum4(vector&lt;int&gt;&amp; nums, int target) {
        m_ = vector&lt;int&gt;(target + 1, -1);
        m_[0] = 1;
        return dp(nums, target);
    }    
private:
    int dp(const vector&lt;int&gt;&amp; nums, int target) {
        if (target &lt; 0) return 0;
        if (m_[target] != -1) return m_[target];
        int ans = 0;
        for (const int num : nums)
            ans += dp(nums, target - num);
        return m_[target] = ans;
    }
    vector&lt;int&gt; m_;
};</pre><p>&nbsp;</p>
<p>C++ / DP</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 3 ms
class Solution {
public:
    int combinationSum4(vector&lt;int&gt;&amp; nums, int target) {
        vector&lt;int&gt; dp(target + 1, 0); // dp[i] # of combinations sum up to i
        dp[0] = 1;
        for (int i = 1; i &lt;= target; ++i)
            for (const int num : nums)
                if (i - num &gt;= 0)
                    dp[i] += dp[i - num];           
        return dp[target];
    }
};</pre><p><strong>Related Problems:</strong></p>
<ul>
<li><a href="http://zxi.mytechroad.com/blog/searching/leetcode-39-combination-sum/">[解题报告] LeetCode 39. Combination Sum</a></li>
<li><a href="http://zxi.mytechroad.com/blog/searching/leetcode-40-combination-sum-ii/">[解题报告] LeetCode 40. Combination Sum II</a></li>
<li><a href="http://zxi.mytechroad.com/blog/searching/leetcode-216-combination-sum-iii/">[解题报告] LeetCode 216. Combination Sum III</a></li>
</ul>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-377-combination-sum-iv/">花花酱 LeetCode 377. Combination Sum IV</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-377-combination-sum-iv/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 210. Course Schedule II</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-210-course-schedule-ii/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-210-course-schedule-ii/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Thu, 14 Dec 2017 06:35:21 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[Medium]]></category>
		<category><![CDATA[cycle]]></category>
		<category><![CDATA[directed graph]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[topological sort]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=1228</guid>

					<description><![CDATA[<p>Problem There are a total of n courses you have to take, labeled from 0 to n - 1. Some courses may have prerequisites, for example to take course 0&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-210-course-schedule-ii/">花花酱 LeetCode 210. Course Schedule II</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/Qqgck2ijUjU?feature=oembed" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></p>
<h1><strong>Problem</strong></h1>
<p>There are a total of <i>n</i> courses you have to take, labeled from <code>0</code> to <code>n - 1</code>.</p>
<p>Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: <code>[0,1]</code></p>
<p>Given the total number of courses and a list of prerequisite <b>pairs</b>, return the ordering of courses you should take to finish all courses.</p>
<p>There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array.</p>
<p>For example:</p><pre class="crayon-plain-tag">2, [[1,0]]</pre><p>There are a total of 2 courses to take. To take course 1 you should have finished course 0. So the correct course order is <code>[0,1]</code></p><pre class="crayon-plain-tag">4, [[1,0],[2,0],[3,1],[3,2]]</pre><p>There are a total of 4 courses to take. To take course 3 you should have finished both courses 1 and 2. Both courses 1 and 2 should be taken after you finished course 0. So one correct course order is <code>[0,1,2,3]</code>. Another correct ordering is<code>[0,2,1,3]</code>.</p>
<p><b>Note:</b></p>
<ol>
<li>The input prerequisites is a graph represented by <b>a list of edges</b>, not adjacency matrices. Read more about <a href="https://www.khanacademy.org/computing/computer-science/algorithms/graph-representation/a/representing-graphs" target="_blank" rel="noopener">how a graph is represented</a>.</li>
<li>You may assume that there are no duplicate edges in the input prerequisites.</li>
</ol>
<p><strong>题目大意：</strong></p>
<p>给你一些课程和它的先修课程，让你输出修课顺序。如果无法修完所有课程，返回空数组。</p>
<p><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><img class="alignnone size-full wp-image-1252" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/210-ep133.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/210-ep133.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/210-ep133-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/210-ep133-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<h1><strong>Idea</strong></h1>
<p>Topological sorting</p>
<p>拓扑排序</p>
<h1><strong>Solution 1: Topological Sorting</strong></h1>
<p>Time complexity: O(V+E)</p>
<p>Space complexity: O(V+E)</p>
<p><div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 16 ms
class Solution {
public:
  vector&lt;int&gt; findOrder(int numCourses, vector&lt;pair&lt;int, int&gt;&gt;&amp; prerequisites) {
    vector&lt;vector&lt;int&gt;&gt; graph(numCourses);    
    for(const auto&amp; p : prerequisites)
      graph[p.second].push_back(p.first);

    // states: 0 = unkonwn, 1 == visiting, 2 = visited
    vector&lt;int&gt; v(numCourses, 0);
    vector&lt;int&gt; ans;
    
    for (int i = 0; i &lt; numCourses; ++i)
      if (dfs(i, graph, v, ans)) return {};

    std::reverse(ans.begin(), ans.end());
    return ans;
  }
private:
  bool dfs(int cur, vector&lt;vector&lt;int&gt;&gt;&amp; graph, vector&lt;int&gt;&amp; v, vector&lt;int&gt;&amp; ans) {
    if (v[cur] == 1) return true;
    if (v[cur] == 2) return false;

    v[cur] = 1;
    
    for (const int t : graph[cur])
      if (dfs(t, graph, v, ans)) return true;
    
    v[cur] = 2;
    ans.push_back(cur);

    return false;
  }
};</pre><p></div><h2 class="tabtitle">Java</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 83 ms
class Solution {
    public int[] findOrder(int numCourses, int[][] prerequisites) {
        ArrayList&lt;ArrayList&lt;Integer&gt;&gt; graph = new ArrayList&lt;&gt;();
        
        for (int i = 0; i &lt; numCourses; ++i)
            graph.add(new ArrayList&lt;Integer&gt;());
        
        for (int i = 0; i &lt; prerequisites.length; ++i) {
            int course = prerequisites[i][0];
            int prerequisite = prerequisites[i][1];            
            graph.get(course).add(prerequisite);
        }
        
        int[] visited = new int[numCourses];
        List&lt;Integer&gt; ans = new ArrayList&lt;Integer&gt;();
        Integer index = numCourses;
        for (int i = 0; i &lt; numCourses; ++i)
            if (dfs(i, graph, visited, ans)) return new int[0];        
        
        return ans.stream().mapToInt(i-&gt;i).toArray();
    }
    
    private boolean dfs(int curr, ArrayList&lt;ArrayList&lt;Integer&gt;&gt; graph, int[] visited, List&lt;Integer&gt; ans) {
        if (visited[curr] == 1) return true;
        if (visited[curr] == 2) return false;
        
        visited[curr] = 1;
        for (int next : graph.get(curr))
            if (dfs(next, graph, visited, ans)) return true;
        
        visited[curr] = 2;
        ans.add(curr);
        
        return false;
    }    
}</pre><p></div></div></p>
<h1><strong>Related Problems:</strong></h1>
<ul>
<li><a href="http://zxi.mytechroad.com/blog/graph/leetcode-207-course-schedule/">[解题报告] LeetCode 207. Course Schedule</a></li>
<li><a href="https://zxi.mytechroad.com/blog/graph/leetcode-802-find-eventual-safe-states/">花花酱 LeetCode 802. Find Eventual Safe States</a></li>
</ul>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-210-course-schedule-ii/">花花酱 LeetCode 210. Course Schedule II</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/graph/leetcode-210-course-schedule-ii/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 742. Closest Leaf in a Binary Tree</title>
		<link>https://zxi.mytechroad.com/blog/tree/742-closest-leaf-in-a-binary-tree/</link>
					<comments>https://zxi.mytechroad.com/blog/tree/742-closest-leaf-in-a-binary-tree/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Wed, 13 Dec 2017 06:21:27 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[Medium]]></category>
		<category><![CDATA[Tree]]></category>
		<category><![CDATA[BFS]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[shortest path]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=1216</guid>

					<description><![CDATA[<p>Problem: Given a binary tree where every node has a unique value, and a target key k, find the value of the closest leaf node to target k in&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/tree/742-closest-leaf-in-a-binary-tree/">花花酱 LeetCode 742. Closest Leaf in a Binary Tree</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/x1wXkRrpavw?feature=oembed" frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen></iframe></p>
<p><strong>Problem:</strong></p>
<p>Given a binary tree <b>where every node has a unique value</b>, and a target key <code>k</code>, find the value of the closest leaf node to target <code>k</code> in the tree.</p>
<p>Here, <i>closest</i> to a leaf means the least number of edges travelled on the binary tree to reach any leaf of the tree. Also, a node is called a <i>leaf</i> if it has no children.</p>
<p>In the following examples, the input tree is represented in flattened form row by row. The actual <code>root</code> tree given will be a TreeNode object.</p>
<p><b>Example 1:</b></p><pre class="crayon-plain-tag">Input:
root = [1, 3, 2], k = 1
Diagram of binary tree:
          1
         / \
        3   2

Output: 2 (or 3)

Explanation: Either 2 or 3 is the closest leaf node to the target of 1.</pre><p><b>Example 2:</b></p><pre class="crayon-plain-tag">Input:
root = [1], k = 1
Output: 1

Explanation: The closest leaf node is the root node itself.</pre><p><b>Example 3:</b></p><pre class="crayon-plain-tag">Input:
root = [1,2,3,4,null,null,null,5,null,6], k = 2
Diagram of binary tree:
             1
            / \
           2   3
          /
         4
        /
       5
      /
     6

Output: 3
Explanation: The leaf node with value 3 (and not the leaf node with value 6) is closest to the node with value 2.</pre><p><b>Note:</b></p>
<ol>
<li><code>root</code> represents a binary tree with at least <code>1</code> node and at most <code>1000</code> nodes.</li>
<li>Every node has a unique <code>node.val</code> in range <code>[1, 1000]</code>.</li>
<li>There exists some node in the given binary tree for which <code>node.val == k</code>.</li>
</ol>
<p><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>题目大意:</strong></p>
<p>给你一棵树，每个节点的值都不相同。</p>
<p>给定一个节点值，让你找到离这个节点距离最近的叶子节点的值。</p>
<p><strong>Idea:</strong></p>
<p>Shortest path from source to any leaf nodes in a undirected unweighted graph.</p>
<p>问题转换为在无向/等权重的图中找一条从起始节点到任意叶子节点最短路径。</p>
<p><img class="alignnone size-full wp-image-1222" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/742-ep131.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/742-ep131.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/742-ep131-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/742-ep131-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p><strong>Solution:</strong></p>
<p>C++ / DFS + BFS</p>
<p>Time complexity: O(n)</p>
<p>Space complexity: O(n)</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 16 ms
class Solution {
public:
    int findClosestLeaf(TreeNode* root, int k) {
        graph_.clear();
        start_ = nullptr;
        buildGraph(root, nullptr, k);
        queue&lt;TreeNode*&gt; q;
        q.push(start_);
        unordered_set&lt;TreeNode*&gt; seen;
        while (!q.empty()) {
            int size = q.size();
            while (size--&gt;0) {
                TreeNode* curr = q.front();
                q.pop();                
                seen.insert(curr);                
                if (!curr-&gt;left &amp;&amp; !curr-&gt;right) return curr-&gt;val;
                for (TreeNode* node : graph_[curr])
                    if (!seen.count(node)) q.push(node);
            }
        }
        return 0;
    }
private:
    void buildGraph(TreeNode* node, TreeNode* parent, int k) {
        if (!node) return;
        if (node-&gt;val == k) start_ = node;
        if (parent) {
            graph_[node].push_back(parent);
            graph_[parent].push_back(node);
        }
        buildGraph(node-&gt;left, node, k);
        buildGraph(node-&gt;right, node, k);
    }
    
    unordered_map&lt;TreeNode*, vector&lt;TreeNode*&gt;&gt; graph_;
    TreeNode* start_;
};</pre><p>&nbsp;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/tree/742-closest-leaf-in-a-binary-tree/">花花酱 LeetCode 742. Closest Leaf in a Binary Tree</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/742-closest-leaf-in-a-binary-tree/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 743. Network Delay Time</title>
		<link>https://zxi.mytechroad.com/blog/graph/leetcode-743-network-delay-time/</link>
					<comments>https://zxi.mytechroad.com/blog/graph/leetcode-743-network-delay-time/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Wed, 13 Dec 2017 01:20:09 +0000</pubDate>
				<category><![CDATA[Graph]]></category>
		<category><![CDATA[Medium]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[shortest path]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=1204</guid>

					<description><![CDATA[<p>There are N network nodes, labelled 1 to N. Given times, a list of travel times as directed edges times[i] = (u, v, w), where u is the source node, v is the target node, and w is the time&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-743-network-delay-time/">花花酱 LeetCode 743. Network Delay Time</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[<div class="question-description">
<p><iframe width="500" height="375" src="https://www.youtube.com/embed/vwLYDeghs_c?feature=oembed" frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen></iframe></p>
<p>There are <code>N</code> network nodes, labelled <code>1</code> to <code>N</code>.</p>
<p>Given <code>times</code>, a list of travel times as <b>directed</b> edges <code>times[i] = (u, v, w)</code>, where <code>u</code> is the source node, <code>v</code> is the target node, and <code>w</code> is the time it takes for a signal to travel from source to target.</p>
<p>Now, we send a signal from a certain node <code>K</code>. How long will it take for all nodes to receive the signal? If it is impossible, return <code>-1</code>.</p>
<p><b>Note:</b></p>
<ol>
<li><code>N</code> will be in the range <code>[1, 100]</code>.</li>
<li><code>K</code> will be in the range <code>[1, N]</code>.</li>
<li>The length of <code>times</code> will be in the range <code>[1, 6000]</code>.</li>
<li>All edges <code>times[i] = (u, v, w)</code> will have <code>1 &lt;= u, v &lt;= N</code> and <code>1 &lt;= w &lt;= 100</code>.</li>
</ol>
<p><strong>Idea:</strong></p>
<p>Construct the graph and do a shortest path from K to all other nodes.</p>
<p><img class="alignnone wp-image-1213 size-full" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/743-ep130.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/743-ep130.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/743-ep130-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/743-ep130-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p><strong>Solution 2:</strong></p>
<p>C++ / Bellman-Ford</p>
<p>Time complexity: O(ne)</p>
<p>Space complexity: O(n)</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 92 ms
class Solution {
public:
    int networkDelayTime(vector&lt;vector&lt;int&gt;&gt;&amp; times, int N, int K) {
        constexpr int MAX_TIME = 101 * 100;
        vector&lt;int&gt; dist(N, MAX_TIME);
        dist[K - 1] = 0;
        for (int i = 1; i &lt; N; ++i)
            for (const auto&amp; time : times) {
                int u = time[0] - 1, v = time[1] - 1, w = time[2];
                dist[v] = min(dist[v], dist[u] + w);
            }
        int max_dist = *max_element(dist.begin(), dist.end());
        return max_dist == MAX_TIME ? -1 : max_dist;
    }
};</pre><p>&nbsp;</p>
</div>
<div></div>
<p><strong>Solution3:</strong></p>
<p>C++ / Floyd-Warshall</p>
<p>Time complexity: O(n^3)</p>
<p>Space complexity: O(n^2)</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 92 ms
class Solution {
public:
    int networkDelayTime(vector&lt;vector&lt;int&gt;&gt;&amp; times, int N, int K) {
        vector&lt;vector&lt;int&gt;&gt; d(N, vector&lt;int&gt;(N, -1));
        
        for (auto time : times)   
            d[time[0] - 1][time[1] - 1] = time[2];
        
        for (int i = 0; i &lt; N; ++i)
            d[i][i] = 0;
        
        for (int k = 0; k &lt; N; ++k)
            for (int i = 0; i &lt; N; ++i)
                for (int j = 0; j &lt; N; ++j)
                    if (d[i][k] &gt;= 0 &amp;&amp; d[k][j] &gt;= 0)
                        if (d[i][j] &lt; 0 || d[i][j] &gt; d[i][k] + d[k][j])
                            d[i][j] = d[i][k] + d[k][j];
        
        int ans = INT_MIN;        
        
        for (int i = 0; i &lt; N; ++i) {
            if (d[K - 1][i] &lt; 0) return -1;
            ans = max(ans, d[K - 1][i]);
        }
        
        return ans;
    }
};</pre><p>v2</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 89 ms
class Solution {
public:
    int networkDelayTime(vector&lt;vector&lt;int&gt;&gt;&amp; times, int N, int K) {
        constexpr int MAX_TIME = 101 * 100;
        vector&lt;vector&lt;int&gt;&gt; d(N, vector&lt;int&gt;(N, MAX_TIME));
        
        for (auto time : times)   
            d[time[0] - 1][time[1] - 1] = time[2];
        
        for (int i = 0; i &lt; N; ++i)
            d[i][i] = 0;
        
        for (int k = 0; k &lt; N; ++k)
            for (int i = 0; i &lt; N; ++i)
                for (int j = 0; j &lt; N; ++j)                    
                    d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
        
        int max_time = *max_element(d[K - 1].begin(), d[K - 1].end());        
        return max_time &gt;= MAX_TIME ? - 1 : max_time;
    }
};</pre><p></p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/graph/leetcode-743-network-delay-time/">花花酱 LeetCode 743. Network Delay Time</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/graph/leetcode-743-network-delay-time/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 740. Delete and Earn</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-740-delete-and-earn/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-740-delete-and-earn/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Wed, 06 Dec 2017 05:40:51 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[Medium]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[house robber]]></category>
		<category><![CDATA[reduction]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=1121</guid>

					<description><![CDATA[<p>Problem: Given an array nums of integers, you can perform operations on the array. In each operation, you pick any nums[i] and delete it to earn nums[i] points. After, you must&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-740-delete-and-earn/">花花酱 LeetCode 740. Delete and Earn</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/YzZd-bsMthk?feature=oembed" frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen></iframe></p>
<p><strong>Problem:</strong></p>
<p>Given an array <code>nums</code> of integers, you can perform operations on the array.</p>
<p>In each operation, you pick any <code>nums[i]</code> and delete it to earn <code>nums[i]</code> points. After, you must delete <b>every</b>element equal to <code>nums[i] - 1</code> or <code>nums[i] + 1</code>.</p>
<p>You start with 0 points. Return the maximum number of points you can earn by applying such operations.</p>
<p><b>Example 1:</b></p><pre class="crayon-plain-tag">Input: nums = [3, 4, 2]
Output: 6
Explanation: 
Delete 4 to earn 4 points, consequently 3 is also deleted.
Then, delete 2 to earn 2 points. 6 total points are earned.</pre><p><b>Example 2:</b></p><pre class="crayon-plain-tag">Input: nums = [2, 2, 3, 3, 3, 4]
Output: 9
Explanation: 
Delete 3 to earn 3 points, deleting both 2's and the 4.
Then, delete 3 again to earn 3 points, and 3 again to earn 3 points.
9 total points are earned.</pre><p><b>Note:</b></p>
<ul>
<li>The length of <code>nums</code> is at most <code>20000</code>.</li>
<li>Each element <code>nums[i]</code> is an integer in the range <code>[1, 10000]</code>.</li>
</ul>
<p><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>Reduce the problem to <a href="http://zxi.mytechroad.com/blog/dynamic-programming/leetcode-198-house-robber/">House Robber Problem</a></p>
<p><span style="font-weight: 400;">Key observations: If we take nums[i]</span></p>
<ol>
<li><span style="font-weight: 400;"> We can safely take all of its copies.</span></li>
<li><span style="font-weight: 400;"> We can’t take any of copies of nums[i &#8211; 1] and nums[i + 1]</span></li>
</ol>
<p><span style="font-weight: 400;">This problem is reduced to 198 House Robber.</span></p>
<p><span style="font-weight: 400;">Houses[i] has all the copies of num whose value is i.</span></p>
<p><span style="font-weight: 400;">[3 4 2] -&gt; [0 2 3 4], rob([0 </span><b>2</b><span style="font-weight: 400;"> 3 </span><b>4</b><span style="font-weight: 400;">]) = 6            </span></p>
<p><span style="font-weight: 400;">[2, 2, 3, 3, 3, 4] -&gt; [0 2*2 3*3 4], rob([0 2*2 </span><b>3*3</b><span style="font-weight: 400;"> 4]) = 9</span></p>
<p><span style="font-weight: 400;">Time complexity: O(n+r) reduction + O(r) solving rob = O(n + r)</span></p>
<p><span style="font-weight: 400;">Space complexity: O(r)</span></p>
<p><span style="font-weight: 400;">r = max(nums) &#8211; min(nums) + 1</span></p>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/740-ep125.png"><img class="alignnone size-full wp-image-1128" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/740-ep125.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/740-ep125.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/740-ep125-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/740-ep125-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<p>Time complexity: O(n + r)</p>
<p>Space complexity: O(r)</p>
<p><strong>Solution:</strong></p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 6 ms
class Solution {
public:
    int deleteAndEarn(vector&lt;int&gt;&amp; nums) {
        if (nums.empty()) return 0;
        const auto range = minmax_element(nums.begin(), nums.end());
        const int l = *(range.first);
        const int r = *(range.second);        
        vector&lt;int&gt; points(r - l + 1, 0);
        for (const int num : nums)
            points[num - l] += num;
        return rob(points);
    }
private:
    // From LeetCode 198. House Robber
    int rob(const vector&lt;int&gt;&amp; nums) {
        int dp2 = 0;
        int dp1 = 0;
        for (int i = 0; i &lt; nums.size() ; ++i) {
            int dp = max(dp2 + nums[i], dp1);
            dp2 = dp1;
            dp1 = dp;
        }
        return dp1;
    }
};</pre><p><strong>Related Problem:</strong></p>
<ul>
<li><a href="http://zxi.mytechroad.com/blog/dynamic-programming/leetcode-198-house-robber/">花花酱 LeetCode 198. House Robber</a></li>
</ul>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-740-delete-and-earn/">花花酱 LeetCode 740. Delete and Earn</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-740-delete-and-earn/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 735. Asteroid Collision</title>
		<link>https://zxi.mytechroad.com/blog/simulation/leetcode-735-asteroid-collision/</link>
					<comments>https://zxi.mytechroad.com/blog/simulation/leetcode-735-asteroid-collision/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 04 Dec 2017 00:30:46 +0000</pubDate>
				<category><![CDATA[Medium]]></category>
		<category><![CDATA[Simulation]]></category>
		<category><![CDATA[simulation]]></category>
		<category><![CDATA[stack]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=1089</guid>

					<description><![CDATA[<p>Problem: We are given an array asteroids of integers representing asteroids in a row. For each asteroid, the absolute value represents its size, and the sign represents&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/simulation/leetcode-735-asteroid-collision/">花花酱 LeetCode 735. Asteroid Collision</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[<div class="question-description">
<p><iframe width="500" height="375" src="https://www.youtube.com/embed/8oOhXcdXbZk?feature=oembed" frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen></iframe></p>
<p><strong>Problem:</strong></p>
<p>We are given an array <code>asteroids</code> of integers representing asteroids in a row.</p>
<p>For each asteroid, the absolute value represents its size, and the sign represents its direction (positive meaning right, negative meaning left). Each asteroid moves at the same speed.</p>
<p>Find out the state of the asteroids after all collisions. If two asteroids meet, the smaller one will explode. If both are the same size, both will explode. Two asteroids moving in the same direction will never meet.</p>
<p><b>Example 1:</b></p><pre class="crayon-plain-tag">Input: 
asteroids = [5, 10, -5]
Output: [5, 10]
Explanation: 
The 10 and -5 collide resulting in 10.  The 5 and 10 never collide.</pre><p><b>Example 2:</b></p><pre class="crayon-plain-tag">Input: 
asteroids = [8, -8]
Output: []
Explanation: 
The 8 and -8 collide exploding each other.</pre><p><b>Example 3:</b></p><pre class="crayon-plain-tag">Input: 
asteroids = [10, 2, -5]
Output: [10]
Explanation: 
The 2 and -5 collide resulting in -5.  The 10 and -5 collide resulting in 10.</pre><p><b>Example 4:</b></p><pre class="crayon-plain-tag">Input: 
asteroids = [-2, -1, 1, 2]
Output: [-2, -1, 1, 2]
Explanation: 
The -2 and -1 are moving left, while the 1 and 2 are moving right.
Asteroids moving the same direction never meet, so no asteroids will meet each other.</pre><p><b>Note:</b></p>
<ul>
<li>The length of <code>asteroids</code> will be at most <code>10000</code>.</li>
<li>Each asteroid will be a non-zero integer in the range <code>[-1000, 1000].</code>.</li>
</ul>
</div>
<div id="interviewed-div"><strong>Idea:</strong></div>
<div>Simulation</div>
<div>
<p><span style="font-weight: 400;">Time complexity: O(n), Space complexity: O(n)</span></p>
</div>
<div><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/735-ep122-1.png"><img class="alignnone size-full wp-image-1095" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/735-ep122-1.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/735-ep122-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/735-ep122-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/735-ep122-1-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></div>
<p><strong>Solution:</strong></p>
<p>C ++</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 22 ms
class Solution {
public:
    vector&lt;int&gt; asteroidCollision(vector&lt;int&gt;&amp; asteroids) {
        vector&lt;int&gt; s;
        for (int i = 0 ; i &lt; asteroids.size(); ++i) {
            const int size = asteroids[i];
            if (size &gt; 0) { // To right, OK
                s.push_back(size);
            } else {
                // To left
                if (s.empty() || s.back() &lt; 0) // OK when all are negtives
                    s.push_back(size);
                else if (abs(s.back()) &lt;= abs(size)) {
                    // Top of the stack is going right.
                    // Its size is less than the current one.
                    
                    // The current one still alive!
                    if (abs(s.back()) &lt; abs(size)) --i;
                    
                    s.pop_back(); // Destory the top one moving right
                }                    
            }
        }
        
        // s must look like [-s1, -s2, ... , si, sj, ...]
        return s;
    }
};</pre><p>&nbsp;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/simulation/leetcode-735-asteroid-collision/">花花酱 LeetCode 735. Asteroid Collision</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/simulation/leetcode-735-asteroid-collision/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 737. Sentence Similarity II</title>
		<link>https://zxi.mytechroad.com/blog/hashtable/leetcode-737-sentence-similarity-ii/</link>
					<comments>https://zxi.mytechroad.com/blog/hashtable/leetcode-737-sentence-similarity-ii/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Tue, 28 Nov 2017 23:04:19 +0000</pubDate>
				<category><![CDATA[Hashtable]]></category>
		<category><![CDATA[Medium]]></category>
		<category><![CDATA[similar]]></category>
		<category><![CDATA[union find]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=1013</guid>

					<description><![CDATA[<p>Problem: Given two sentences words1, words2 (each represented as an array of strings), and a list of similar word pairs pairs, determine if two sentences are similar. For&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/hashtable/leetcode-737-sentence-similarity-ii/">花花酱 LeetCode 737. Sentence Similarity II</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/0rZUi3kZGLI?feature=oembed" frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen></iframe></p>
<p><strong>Problem:</strong></p>
<p>Given two sentences <code>words1, words2</code> (each represented as an array of strings), and a list of similar word pairs <code>pairs</code>, determine if two sentences are similar.</p>
<p>For example, <code>words1 = ["great", "acting", "skills"]</code> and <code>words2 = ["fine", "drama", "talent"]</code> are similar, if the similar word pairs are <code>pairs = [["great", "good"], ["fine", "good"], ["acting","drama"], ["skills","talent"]]</code>.</p>
<p>Note that the similarity relation <b>is</b> transitive. For example, if &#8220;great&#8221; and &#8220;good&#8221; are similar, and &#8220;fine&#8221; and &#8220;good&#8221; are similar, then &#8220;great&#8221; and &#8220;fine&#8221; <b>are similar</b>.</p>
<p>Similarity is also symmetric. For example, &#8220;great&#8221; and &#8220;fine&#8221; being similar is the same as &#8220;fine&#8221; and &#8220;great&#8221; being similar.</p>
<p>Also, a word is always similar with itself. For example, the sentences <code>words1 = ["great"], words2 = ["great"], pairs = []</code> are similar, even though there are no specified similar word pairs.</p>
<p>Finally, sentences can only be similar if they have the same number of words. So a sentence like <code>words1 = ["great"]</code> can never be similar to <code>words2 = ["doubleplus","good"]</code>.</p>
<p><b>Note:</b></p>
<ul>
<li>The length of <code>words1</code> and <code>words2</code> will not exceed <code>1000</code>.</li>
<li>The length of <code>pairs</code> will not exceed <code>2000</code>.</li>
<li>The length of each <code>pairs[i]</code> will be <code>2</code>.</li>
<li>The length of each <code>words[i]</code> and <code>pairs[i][j]</code> will be in the range <code>[1, 20]</code>.</li>
</ul>
<p><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>题目大意：</p>
<p>给你两个句子（由单词数组表示）和一些近义词对，问你这两个句子是否相似，即每组相对应的单词都要相似。</p>
<p>注意相似性可以传递，比如只给你&#8221;great&#8221;和&#8221;fine&#8221;相似、&#8221;fine&#8221;和&#8221;good&#8221;相似，能推断&#8221;great&#8221;和&#8221;good&#8221;也相似。</p>
<p><strong>Idea:</strong></p>
<p>DFS / Union Find</p>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/737-ep118.png"><img class="alignnone size-full wp-image-1034" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/737-ep118.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/737-ep118.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/737-ep118-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/737-ep118-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<p><strong>Solution1:</strong></p>
<p>Time complexity: O(|Pairs| * |words1|)</p>
<p>Space complexity: O(|Pairs|)</p>
<p>C++ / DFS</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 346 ms
class Solution {
public:
    bool areSentencesSimilarTwo(vector&lt;string&gt;&amp; words1, vector&lt;string&gt;&amp; words2, vector&lt;pair&lt;string, string&gt;&gt;&amp; pairs) {
        if (words1.size() != words2.size()) return false;
        
        g_.clear();
        
        for (const auto&amp; p : pairs) {
            g_[p.first].insert(p.second);
            g_[p.second].insert(p.first);
        }
        
        unordered_set&lt;string&gt; visited;
        
        for (int i = 0; i &lt; words1.size(); ++i) {
            visited.clear();
            if (!dfs(words1[i], words2[i], visited)) return false;
        }
        
        return true;
    }
private:
    bool dfs(const string&amp; src, const string&amp; dst, unordered_set&lt;string&gt;&amp; visited) {
        if (src == dst) return true;
        visited.insert(src);
        for (const auto&amp; next : g_[src]) {
            if (visited.count(next)) continue;
            if (dfs(next, dst, visited)) return true;
        }
        return false;
    }
    unordered_map&lt;string, unordered_set&lt;string&gt;&gt; g_;
};</pre><p>Time complexity: O(|Pairs| + |words1|)</p>
<p>Space complexity: O(|Pairs|)</p>
<p>C++ / DFS Optimized</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime 229 ms
class Solution {
public:
    bool areSentencesSimilarTwo(vector&lt;string&gt;&amp; words1, vector&lt;string&gt;&amp; words2, vector&lt;pair&lt;string, string&gt;&gt;&amp; pairs) {
        if (words1.size() != words2.size()) return false;
        
        g_.clear();
        ids_.clear();
        
        for (const auto&amp; p : pairs) {
            g_[p.first].insert(p.second);
            g_[p.second].insert(p.first);
        }        
        
        int id = 0;
        
        for (const auto&amp; p : pairs) {
            if(!ids_.count(p.first)) dfs(p.first, ++id);
            if(!ids_.count(p.second)) dfs(p.second, ++id);
        }
        
        for (int i = 0; i &lt; words1.size(); ++i) {
            if (words1[i] == words2[i]) continue;
            auto it1 = ids_.find(words1[i]);
            auto it2 = ids_.find(words2[i]);
            if (it1 == ids_.end() || it2 == ids_.end()) return false;
            if (it1-&gt;second != it2-&gt;second) return false;
        }
        
        return true;
    }
private:
    bool dfs(const string&amp; curr, int id) {
        ids_[curr] = id;        
        for (const auto&amp; next : g_[curr]) {
            if (ids_.count(next)) continue;
            if (dfs(next, id)) return true;
        }
        return false;
    }
    
    unordered_map&lt;string, int&gt; ids_;
    unordered_map&lt;string, unordered_set&lt;string&gt;&gt; g_;
};</pre><p>&nbsp;</p>
<p><strong>Solution2:</strong></p>
<p>Time complexity: O(|Pairs| + |words1|)</p>
<p>Space complexity: O(|Pairs|)</p>
<p>C++ / Union Find</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 219 ms
class UnionFindSet {
public:
    bool Union(const string&amp; word1, const string&amp; word2) {
        const string&amp; p1 = Find(word1, true);
        const string&amp; p2 = Find(word2, true);
        if (p1 == p2) return false;        
        parents_[p1] = p2;
        return true;
    }
    
    const string&amp; Find(const string&amp; word, bool create = false) {
        if (!parents_.count(word)) {
            if (!create) return word;
            return parents_[word] = word;
        }
        
        string w = word;
        while (w != parents_[w]) {
            parents_[w] = parents_[parents_[w]];
            w = parents_[w];
        }
        
        return parents_[w];
    }
private:
    unordered_map&lt;string, string&gt; parents_;
};

class Solution {
public:
    bool areSentencesSimilarTwo(vector&lt;string&gt;&amp; words1, vector&lt;string&gt;&amp; words2, vector&lt;pair&lt;string, string&gt;&gt;&amp; pairs) {
        if (words1.size() != words2.size()) return false;
        
        UnionFindSet s;
        for (const auto&amp; pair : pairs)
            s.Union(pair.first, pair.second);
        
        for (int i = 0; i &lt; words1.size(); ++i) 
            if (s.Find(words1[i]) != s.Find(words2[i])) return false;
        
        return true;
    }
};</pre><p>&nbsp;</p>
<p>C++ / Union Find, Optimized</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 175 ms (&lt; 98.45%)
class UnionFindSet {
public:
    UnionFindSet(int n) {
        parents_ = vector&lt;int&gt;(n + 1, 0);
        ranks_ = vector&lt;int&gt;(n + 1, 0);
        
        for (int i = 0; i &lt; parents_.size(); ++i)
            parents_[i] = i;
    }
    
    bool Union(int u, int v) {
        int pu = Find(u);
        int pv = Find(v);
        if (pu == pv) return false;
        
        if (ranks_[pu] &gt; ranks_[pv]) {
            parents_[pv] = pu;
        } else if (ranks_[pv] &gt; ranks_[pu]) {
            parents_[pu] = pv;
        } else {
            parents_[pu] = pv;
            ++ranks_[pv];
        }

        return true;
    }
    
    int Find(int id) {        
        if (id != parents_[id])
            parents_[id] = Find(parents_[id]);        
        return parents_[id];
    }
    
private:
    vector&lt;int&gt; parents_;
    vector&lt;int&gt; ranks_;
};

class Solution {
public:
    bool areSentencesSimilarTwo(vector&lt;string&gt;&amp; words1, vector&lt;string&gt;&amp; words2, vector&lt;pair&lt;string, string&gt;&gt;&amp; pairs) {
        if (words1.size() != words2.size()) return false;
        
        UnionFindSet s(pairs.size() * 2);
        
        unordered_map&lt;string, int&gt; indies; // word to index
        
        for (const auto&amp; pair : pairs) {
            int u = getIndex(pair.first, indies, true);
            int v = getIndex(pair.second, indies, true);
            s.Union(u, v);
        }
        
        for (int i = 0; i &lt; words1.size(); ++i) {
            if (words1[i] == words2[i]) continue;
            int u = getIndex(words1[i], indies);
            int v = getIndex(words2[i], indies);
            if (u &lt; 0 || v &lt; 0) return false;
            if (s.Find(u) != s.Find(v)) return false;
        }
        
        return true;
    }
private:
    int getIndex(const string&amp; word, unordered_map&lt;string, int&gt;&amp; indies, bool create = false) {
        auto it = indies.find(word);
        if (it == indies.end()) {
            if (!create) return INT_MIN;
            int index = indies.size();
            indies.emplace(word, index);
            return index;
        }
        
        return it-&gt;second;
    }
};</pre><p><strong>Related Problems:</strong></p>
<ul>
<li><a href="http://zxi.mytechroad.com/blog/hashtable/leetcode-734-sentence-similarity/">[解题报告] LeetCode 734. Sentence Similarity</a></li>
<li><a href="http://zxi.mytechroad.com/blog/tree/leetcode-684-redundant-connection/">[解题报告] LeetCode 684. Redundant Connection</a></li>
<li><a href="http://zxi.mytechroad.com/blog/graph/leetcode-685-redundant-connection-ii/">[解题报告] LeetCode 685. Redundant Connection II</a></li>
</ul>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/hashtable/leetcode-737-sentence-similarity-ii/">花花酱 LeetCode 737. Sentence Similarity II</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-737-sentence-similarity-ii/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 64. Minimum Path Sum</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-64-minimum-path-sum/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-64-minimum-path-sum/#comments</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Tue, 28 Nov 2017 06:33:06 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[Medium]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[memoization]]></category>
		<category><![CDATA[recursion]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=982</guid>

					<description><![CDATA[<p>Problem: Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path. Note: You&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-64-minimum-path-sum/">花花酱 LeetCode 64. Minimum 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[<p><iframe width="500" height="375" src="https://www.youtube.com/embed/Num2bcAu0Sk?feature=oembed" frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen></iframe></p>
<p><strong>Problem:</strong></p>
<p>Given a <i>m</i> x <i>n</i> grid filled with non-negative numbers, find a path from top left to bottom right which <i>minimizes</i> the sum of all numbers along its path.</p>
<p><b>Note:</b> You can only move either down or right at any point in time.</p>
<p><b>Example 1:</b></p><pre class="crayon-plain-tag">[[1,3,1],
 [1,5,1],
 [4,2,1]]</pre><p>Given the above grid map, return <code>7</code>. Because the path 1→3→1→1→1 minimizes the sum.</p>
<p>&nbsp;</p>
<p><strong>Idea:</strong></p>
<p>DP</p>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/64-ep115.png"><img class="alignnone size-full wp-image-989" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/64-ep115.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/64-ep115.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/64-ep115-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/64-ep115-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<p><strong>Solution 1:</strong></p>
<p>C++ / Recursion with memoization</p>
<p>Time complexity: O(mn)</p>
<p>Space complexity: O(mn)</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 9 ms
class Solution {
public:
    int minPathSum(vector&lt;vector&lt;int&gt;&gt;&amp; grid) {
        int m = grid.size();
        if (m == 0) return 0;
        int n = grid[0].size();
        
        s_ = vector&lt;vector&lt;int&gt;&gt;(m, vector&lt;int&gt;(n, 0));
        
        return minPathSum(grid, n - 1, m - 1, n, m);
    }    
private:
    long minPathSum(const vector&lt;vector&lt;int&gt;&gt;&amp; grid, 
                   int x, int y, int n, int m) {        
        if (x == 0 &amp;&amp; y == 0) return grid[y][x];
        if (x &lt; 0 || y &lt; 0) return INT_MAX;
        if (s_[y][x] &gt; 0) return s_[y][x];
        
        int ans = grid[y][x] + min(minPathSum(grid, x - 1, y, n, m),
                                   minPathSum(grid, x, y - 1, n, m));
        return s_[y][x] = ans;
    }
    
    vector&lt;vector&lt;int&gt;&gt; s_;
};</pre><p><strong>Solution 2:</strong></p>
<p>C++ / DP</p>
<p>Time complexity: O(mn)</p>
<p>Space complexity: O(1)</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 9 ms
class Solution {
public:
    int minPathSum(vector&lt;vector&lt;int&gt;&gt;&amp; grid) {
        int m = grid.size();
        if (m == 0) return 0;
        int n = grid[0].size();
        
        for (int i = 0; i &lt; m; ++i)
            for (int j = 0; j &lt; n; ++j) {
                if (i == 0 &amp;&amp; j == 0) continue;
                if (i == 0) 
                    grid[i][j] += grid[i][j - 1];
                else if (j == 0)
                    grid[i][j] += grid[i - 1][j];
                else
                    grid[i][j] += min(grid[i][j - 1], grid[i - 1][j]);
            }
        
        return grid[m - 1][n - 1];
    }    
};</pre><p><strong>Related Problems:</strong></p>
<ul>
<li><a href="http://zxi.mytechroad.com/blog/tree/leetcode-113-path-sum-ii/">[解题报告] LeetCode 113. Path Sum II</a></li>
</ul>
<p>&nbsp;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-64-minimum-path-sum/">花花酱 LeetCode 64. Minimum 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-64-minimum-path-sum/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 113. Path Sum II</title>
		<link>https://zxi.mytechroad.com/blog/tree/leetcode-113-path-sum-ii/</link>
					<comments>https://zxi.mytechroad.com/blog/tree/leetcode-113-path-sum-ii/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Tue, 28 Nov 2017 05:14:24 +0000</pubDate>
				<category><![CDATA[Medium]]></category>
		<category><![CDATA[Tree]]></category>
		<category><![CDATA[path sum]]></category>
		<category><![CDATA[recursion]]></category>
		<category><![CDATA[sum]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=952</guid>

					<description><![CDATA[<p>Problem: Given a binary tree and a sum, find all root-to-leaf paths where each path&#8217;s sum equals the given sum. For example: Given the below&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/tree/leetcode-113-path-sum-ii/">花花酱 LeetCode 113. Path Sum II</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/zrN2dxtQ0f0?feature=oembed" frameborder="0" gesture="media" allowfullscreen></iframe></p>
<p><strong>Problem:</strong></p>
<div class="question-description">
<p>Given a binary tree and a sum, find all root-to-leaf paths where each path&#8217;s sum equals the given sum.</p>
<p>For example:<br />
Given the below binary tree and <code>sum = 22</code>,</p><pre class="crayon-plain-tag">5
             / \
            4   8
           /   / \
          11  13  4
         /  \    / \
        7    2  5   1</pre><p>return</p><pre class="crayon-plain-tag">[
   [5,4,11,2],
   [5,8,4,5]
]</pre><p>
</div>
<div id="interviewed-div"><strong>Idea:</strong></div>
<div>Recursion</div>
<div></div>
<div><strong>Solution:</strong></div>
<div>C++</div>
<div></div>
<div>
</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 9 ms
class Solution {
public:
    vector&lt;vector&lt;int&gt;&gt; pathSum(TreeNode* root, int sum) {
        vector&lt;vector&lt;int&gt;&gt; ans;
        vector&lt;int&gt; curr;
        pathSum(root, sum, curr, ans);
        return ans;
    }
private:
    void pathSum(TreeNode* root, int sum, vector&lt;int&gt;&amp; curr, vector&lt;vector&lt;int&gt;&gt;&amp; ans) {
        if(root==nullptr) return;
        if(root-&gt;left==nullptr &amp;&amp; root-&gt;right==nullptr) {
            if(root-&gt;val == sum) {
                ans.push_back(curr);
                ans.back().push_back(root-&gt;val);
            }
            return;
        }
        
        curr.push_back(root-&gt;val);
        int new_sum = sum - root-&gt;val;
        pathSum(root-&gt;left, new_sum, curr, ans);
        pathSum(root-&gt;right, new_sum, curr, ans);
        curr.pop_back();
    }
};</pre><p><strong>Related Problems:</strong></p>
<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>
<li><a href="http://zxi.mytechroad.com/blog/tree/leetcode-543-diameter-of-binary-tree/">[解题报告] LeetCode 543. Diameter of Binary Tree</a></li>
<li><a href="http://zxi.mytechroad.com/blog/tree/leetcode-687-longest-univalue-path/">[解题报告] LeetCode 687. Longest Univalue Path</a></li>
<li></li>
</ul>
</div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/tree/leetcode-113-path-sum-ii/">花花酱 LeetCode 113. Path Sum II</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-113-path-sum-ii/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
