<?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>Hard Archives - Huahua&#039;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/category/difficulty/hard/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog/category/difficulty/hard/</link>
	<description></description>
	<lastBuildDate>Mon, 30 Sep 2019 04:38:14 +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>Hard Archives - Huahua&#039;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog/category/difficulty/hard/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>花花酱 LeetCode 282. Expression Add Operators</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-282-expression-add-operators/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-282-expression-add-operators/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Wed, 31 Jan 2018 07:00:21 +0000</pubDate>
				<category><![CDATA[Hard]]></category>
		<category><![CDATA[Search]]></category>
		<category><![CDATA[String]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[expression]]></category>
		<category><![CDATA[hard]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=1707</guid>

					<description><![CDATA[<p>题目大意：给你一个字符串，让你在数字之间加上+,-,*使得等式的值等于target。让你输出所有满足条件的表达式。 Given a string that contains only digits 0-9 and a target value, return all possibilities to add binary operators (not unary) +, -, or * between the digits so they evaluate to&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-282-expression-add-operators/">花花酱 LeetCode 282. Expression Add Operators</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/v05R1OIIg08?feature=oembed" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></p>
<p>题目大意：给你一个字符串，让你在数字之间加上+,-,*使得等式的值等于target。让你输出所有满足条件的表达式。</p>
<p>Given a string that contains only digits <code>0-9</code> and a target value, return all possibilities to add <b>binary</b> operators (not unary) <code>+</code>, <code>-</code>, or <code>*</code> between the digits so they evaluate to the target value.</p>
<p>Examples:</p><pre class="crayon-plain-tag">"123", 6 -&gt; ["1+2+3", "1*2*3"] 
"232", 8 -&gt; ["2*3+2", "2+3*2"]
"105", 5 -&gt; ["1*0+5","10-5"]
"00", 0 -&gt; ["0+0", "0-0", "0*0"]
"3456237490", 9191 -&gt; []</pre><p><strong>Slides:</strong></p>
<p><img class="alignnone size-full wp-image-1730" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/282-ep163-1.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/282-ep163-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/282-ep163-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/282-ep163-1-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p><img class="alignnone size-full wp-image-1729" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/282-ep163-2.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/282-ep163-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/282-ep163-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/282-ep163-2-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"> </ins></p>
<h1><strong>Solution 1: DFS</strong></h1>
<p>Time complexity: O(4^n)</p>
<p>Space complexity: O(n^2) -&gt; 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: 128 ms (&lt;79.97%)
class Solution {
public:
  vector&lt;string&gt; addOperators(string num, int target) {
    vector&lt;string&gt; ans;
    dfs(num, target, 0, "", 0, 0, &amp;ans);
    return ans;
  }
private:
  void dfs(const string&amp; num, const int target,  // input
           int pos, const string&amp; exp, long prev, long curr, // state
           vector&lt;string&gt;* ans) {  // output
    if (pos == num.length()) {
      if (curr == target) ans-&gt;push_back(exp);
      return;
    }
    
    for (int l = 1; l &lt;= num.size() - pos; ++l) {
      string t = num.substr(pos, l);    
      if (t[0] == '0' &amp;&amp; t.length() &gt; 1) break; // 0X...
      long n = std::stol(t);
      if (n &gt; INT_MAX) break;
      if (pos == 0) {
        dfs(num, target, l, t, n, n, ans);
        continue;
      }
      dfs(num, target, pos + l, exp + '+' + t, n, curr + n, ans);
      dfs(num, target, pos + l, exp + '-' + t, -n, curr - n, ans);
      dfs(num, target, pos + l, exp + '*' + t, prev * n, curr - prev + prev * n, ans);
    }    
  }
};</pre><p></div><h2 class="tabtitle">C++ / SC O(n)</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 13 ms (&lt; 99.14%)
class Solution {
public:
  vector&lt;string&gt; addOperators(string num, int target) {
    vector&lt;string&gt; ans;
    string exp(num.length() * 2, '\0');    
    dfs(num, target, 0, exp, 0, 0, 0, &amp;ans);
    return ans;
  }
private:
  void dfs(const string&amp; num, const int target,
           int pos, string&amp; exp, int len, long prev, long curr,
           vector&lt;string&gt;* ans) {    
    if (pos == num.length()) {      
      if (curr == target) ans-&gt;push_back(exp.substr(0, len));
      return;
    }
    
    long n = 0;
    int s = pos;
    int l = len;
    if (s != 0) ++len;    
    while (pos &lt; num.size()) {      
      n = n * 10 + (num[pos] - '0');
      if (num[s] == '0' &amp;&amp; pos - s &gt; 0) break; // 0X... invalid number
      if (n &gt; INT_MAX) break; // too long
      exp[len++] = num[pos++];
      if (s == 0) {
        dfs(num, target, pos, exp, len, n, n, ans);
        continue;
      }
      exp[l] = '+'; dfs(num, target, pos, exp, len, n, curr + n, ans);
      exp[l] = '-'; dfs(num, target, pos, exp, len, -n, curr - n, ans);
      exp[l] = '*'; dfs(num, target, pos, exp, len, prev * n, curr - prev + prev * n, ans);
    }
  }
};</pre><p></div><h2 class="tabtitle">Java</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 16 ms (&lt;99.17%)
class Solution {
  private List&lt;String&gt; ans;
  private char[] num;
  private char[] exp;
  private int target;
  
  public List&lt;String&gt; addOperators(String num, int target) {
    this.num = num.toCharArray();
    this.ans = new ArrayList&lt;&gt;();
    this.target = target;
    this.exp = new char[num.length() * 2];
    dfs(0, 0, 0, 0);
    return ans;
  }
  
  private void dfs(int pos, int len, long prev, long curr) {
    if (pos == num.length) {      
      if (curr == target)
        ans.add(new String(exp, 0, len));
      return;
    }
    
    int s = pos;
    int l = len;
    if (s != 0) ++len;
    
    long n = 0;
    while (pos &lt; num.length) {
      if (num[s] == '0' &amp;&amp; pos - s &gt; 0) break; // 0X...
      n = n * 10 + (int)(num[pos] - '0');      
      if (n &gt; Integer.MAX_VALUE) break; // too long
      exp[len++] = num[pos++]; // copy exp
      if (s == 0) {
        dfs(pos, len, n, n);
        continue;
      }
      exp[l] = '+'; dfs(pos, len, n, curr + n);
      exp[l] = '-'; dfs(pos, len, -n, curr - n);
      exp[l] = '*'; dfs(pos, len, prev * n, curr - prev + prev * n);
    }
  }
}</pre><p></div></div></p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-282-expression-add-operators/">花花酱 LeetCode 282. Expression Add Operators</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-282-expression-add-operators/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 480. Sliding Window Median</title>
		<link>https://zxi.mytechroad.com/blog/algorithms/array/leetcode-480-sliding-window-median/</link>
					<comments>https://zxi.mytechroad.com/blog/algorithms/array/leetcode-480-sliding-window-median/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 28 Jan 2018 08:56:53 +0000</pubDate>
				<category><![CDATA[Array]]></category>
		<category><![CDATA[Hard]]></category>
		<category><![CDATA[binary search]]></category>
		<category><![CDATA[median]]></category>
		<category><![CDATA[sliding window]]></category>
		<category><![CDATA[sorting]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=1672</guid>

					<description><![CDATA[<p>题目大意：让你求移动窗口的中位数。 Problem: Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value.&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/algorithms/array/leetcode-480-sliding-window-median/">花花酱 LeetCode 480. Sliding Window Median</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/kDS6ScZwNnI?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></p>
<p>题目大意：让你求移动窗口的中位数。</p>
<p><strong>Problem:</strong></p>
<p>Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value.</p>
<p>Examples:</p>
<p><code>[2,3,4]</code>&nbsp;, the median is&nbsp;<code>3</code></p>
<p><code>[2,3]</code>, the median is&nbsp;<code>(2 + 3) / 2 = 2.5</code></p>
<p>Given an array&nbsp;<i>nums</i>, there is a sliding window of size&nbsp;<i>k</i>&nbsp;which is moving from the very left of the array to the very right. You can only see the&nbsp;<i>k</i>&nbsp;numbers in the window. Each time the sliding window moves right by one position. Your job is to output the median array for each window in the original array.</p>
<p>For example,<br />
Given&nbsp;<i>nums</i>&nbsp;=&nbsp;<code>[1,3,-1,-3,5,3,6,7]</code>, and&nbsp;<i>k</i>&nbsp;= 3.</p><pre class="crayon-plain-tag">Window position                Median
---------------               -----
[1  3  -1] -3  5  3  6  7       1
 1 [3  -1  -3] 5  3  6  7       -1
 1  3 [-1  -3  5] 3  6  7       -1
 1  3  -1 [-3  5  3] 6  7       3
 1  3  -1  -3 [5  3  6] 7       5
 1  3  -1  -3  5 [3  6  7]      6</pre><p>Therefore, return the median sliding window as&nbsp;<code>[1,-1,-1,3,5,6]</code>.</p>
<p><b>Note:&nbsp;</b><br />
You may assume&nbsp;<code>k</code>&nbsp;is always valid, ie:&nbsp;<code>k</code>&nbsp;is always smaller than input array&#8217;s size for non-empty array.</p>
<p><script async="" src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script><br />
<ins class="adsbygoogle" style="display:block" data-ad-format="fluid" data-ad-layout-key="-fb+5w+4e-db+86" data-ad-client="ca-pub-2404451723245401" data-ad-slot="2162692788"></ins><br />
<script><br />
     (adsbygoogle = window.adsbygoogle || []).push({});<br />
</script></p>
<p><img class="alignnone size-full wp-image-1695" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/480-ep162-0.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/480-ep162-0.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/480-ep162-0-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/480-ep162-0-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p><img class="alignnone size-full wp-image-1696" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/480-ep162-2.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/480-ep162-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/480-ep162-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/480-ep162-2-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p><img class="alignnone size-full wp-image-1698" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/480-ep162-2-1.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/480-ep162-2-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/480-ep162-2-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/480-ep162-2-1-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p><strong>Solution 0: Brute Force</strong></p>
<p>Time complexity: O(n*klogk) TLE 32/42 test cases passed</p>
<p><b>Solution 1: Insertion&nbsp;Sort</b></p>
<p>Time complexity: O(k*logk +&nbsp; (n &#8211; k + 1)*k)</p>
<p>Space complexity: O(k)</p>
<p>C++ / vector</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 99 ms
class Solution {
public:
  vector&lt;double&gt; medianSlidingWindow(vector&lt;int&gt;&amp; nums, int k) {    
    vector&lt;double&gt; ans;
    if (k == 0) return ans;
    vector&lt;int&gt; window(nums.begin(), nums.begin() + k - 1);
    std::sort(window.begin(), window.end());
    for (int i = k - 1; i &lt; nums.size(); ++i) {
      window.push_back(nums[i]);
      auto it = prev(window.end(), 1);
      auto const insertion_point = 
              std::upper_bound(window.begin(), it, *it);      
      std::rotate(insertion_point, it, it + 1);          
      ans.push_back((static_cast&lt;double&gt;(window[k / 2]) + window[(k - 1) / 2]) / 2);
      window.erase(std::find(window.begin(), window.end(), nums[i - k + 1]));      
    }
    return ans;
  }
};</pre><p>C++ / vector + binary_search for deletion.</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 84 ms
class Solution {
public:
  vector&lt;double&gt; medianSlidingWindow(vector&lt;int&gt;&amp; nums, int k) {    
    vector&lt;double&gt; ans;
    if (k == 0) return ans;
    vector&lt;int&gt; window(nums.begin(), nums.begin() + k - 1);
    std::sort(window.begin(), window.end());
    for (int i = k - 1; i &lt; nums.size(); ++i) {
      window.push_back(nums[i]);
      auto it = prev(window.end(), 1);
      auto const insertion_point = 
              std::upper_bound(window.begin(), it, *it);      
      std::rotate(insertion_point, it, it + 1);          
      ans.push_back((static_cast&lt;double&gt;(window[k / 2]) + window[(k - 1) / 2]) / 2);
      window.erase(std::lower_bound(window.begin(), window.end(), nums[i - k + 1]));      
    }
    return ans;
  }
};</pre><p>Java</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 60 ms
class Solution {
  public double[] medianSlidingWindow(int[] nums, int k) {
    if (k == 0) return new double[0];
    double[] ans = new double[nums.length - k + 1];
    int[] window = new int[k];
    for (int i = 0; i &lt; k; ++i) 
      window[i] = nums[i];
    Arrays.sort(window);
    for (int i = k; i &lt;= nums.length; ++i) {
      ans[i - k] = ((double)window[k / 2] + window[(k - 1)/2]) / 2;
      if (i == nums.length) break;
      remove(window, nums[i - k]);
      insert(window, nums[i]);
    }
    return ans;
  }
  
  // Insert val into window, window[k - 1] is empty before inseration
  private void insert(int[] window, int val) {
    int i = 0;
    while (i &lt; window.length - 1 &amp;&amp; val &gt; window[i]) ++i;
    int j = window.length - 1;
    while (j &gt; i) window[j] = window[--j];
    window[j] = val;
  }
  
  // Remove val from window and shrink it.
  private void remove(int[] window, int val) {
    int i = 0;
    while (i &lt; window.length &amp;&amp; val != window[i]) ++i;
    while (i &lt; window.length - 1) window[i] = window[++i];
  }
}</pre><p>Java / Binary Search</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 47 ms (&lt;98.96%)
class Solution {
  public double[] medianSlidingWindow(int[] nums, int k) {
    if (k == 0) return new double[0];
    double[] ans = new double[nums.length - k + 1];
    int[] window = new int[k];
    for (int i = 0; i &lt; k; ++i) 
      window[i] = nums[i];
    Arrays.sort(window);
    for (int i = k; i &lt;= nums.length; ++i) {
      ans[i - k] = ((double)window[k / 2] + window[(k - 1)/2]) / 2;
      if (i == nums.length) break;
      remove(window, nums[i - k]);
      insert(window, nums[i]);
    }
    return ans;
  }
  
  // Insert val into window, window[k - 1] is empty before inseration
  private void insert(int[] window, int val) {
    int i = Arrays.binarySearch(window, val);
    if (i &lt; 0) i = - i - 1;    
    int j = window.length - 1;
    while (j &gt; i) window[j] = window[--j];
    window[j] = val;
  }
  
  // Remove val from window and shrink it.
  private void remove(int[] window, int val) {
    int i = Arrays.binarySearch(window, val);
    while (i &lt; window.length - 1) window[i] = window[++i];
  }
  
  
}</pre><p>&nbsp;</p>
<p>Python</p><pre class="crayon-plain-tag">"""
Author: Huahua
Running time: 161 ms (&lt; 93.75%)
"""
class Solution:
  def medianSlidingWindow(self, nums, k):
    if k == 0: return []
    ans = []
    window = sorted(nums[0:k])
    for i in range(k, len(nums) + 1):
      ans.append((window[k // 2] + window[(k - 1) // 2]) / 2.0)
      if i == len(nums): break
      index = bisect.bisect_left(window, nums[i - k])
      window.pop(index)      
      bisect.insort_left(window, nums[i])
    return ans</pre><p><strong>Solution 2: BST</strong></p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 68 ms
class Solution {
public:
  vector&lt;double&gt; medianSlidingWindow(vector&lt;int&gt;&amp; nums, int k) {    
    vector&lt;double&gt; ans;
    if (k == 0) return ans;
    multiset&lt;int&gt; window(nums.begin(), nums.begin() + k);
    auto mid = next(window.begin(), (k - 1) / 2);    
    for (int i = k; i &lt;= nums.size(); ++i) {
      ans.push_back((static_cast&lt;double&gt;(*mid) + 
                     *next(mid, (k + 1) % 2)) / 2.0);
      if (i == nums.size()) break;
      
      window.insert(nums[i]);
      if (nums[i] &lt; *mid) --mid; 
      if (nums[i - k] &lt;= *mid) ++mid;
      window.erase(window.lower_bound(nums[i - k])); 
    }
    return ans;
  }
};</pre><p>&nbsp;</p>
<p><strong>Related Problems:</strong></p>
<ul>
<li><a href="http://zxi.mytechroad.com/blog/leetcode/leetcode-295-find-median-from-data-stream/">[解题报告] LeetCode 295. Find Median from Data Stream O(logn) + O(1)</a></li>
<li><a href="http://zxi.mytechroad.com/blog/heap/leetcode-239-sliding-window-maximum/">花花酱 LeetCode 239. Sliding Window Maximum</a></li>
</ul>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/algorithms/array/leetcode-480-sliding-window-median/">花花酱 LeetCode 480. Sliding Window Median</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/algorithms/array/leetcode-480-sliding-window-median/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 759. Employee Free Time</title>
		<link>https://zxi.mytechroad.com/blog/geometry/leetcode-759-employee-free-time/</link>
					<comments>https://zxi.mytechroad.com/blog/geometry/leetcode-759-employee-free-time/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Tue, 09 Jan 2018 02:11:26 +0000</pubDate>
				<category><![CDATA[Geometry]]></category>
		<category><![CDATA[Hard]]></category>
		<category><![CDATA[intersection]]></category>
		<category><![CDATA[interval]]></category>
		<category><![CDATA[sorting]]></category>
		<category><![CDATA[sweep line]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=1574</guid>

					<description><![CDATA[<p>题目大意：给你每个员工的日历，让你找出所有员工都有空的时间段。 Problem: We are given a list schedule of employees, which represents the working time for each employee. Each employee has a list of non-overlapping Intervals, and these&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/geometry/leetcode-759-employee-free-time/">花花酱 LeetCode 759. Employee Free 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[<p><iframe width="500" height="375" src="https://www.youtube.com/embed/VTgF52uGK0Y?feature=oembed" frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen></iframe></p>
<p>题目大意：给你每个员工的日历，让你找出所有员工都有空的时间段。</p>
<p><strong>Problem:</strong></p>
<p>We are given a list <code>schedule</code> of employees, which represents the working time for each employee.</p>
<p>Each employee has a list of non-overlapping <code>Intervals</code>, and these intervals are in sorted order.</p>
<p>Return the list of finite intervals representing <b>common, positive-length free time</b> for <i>all</i> employees, also in sorted order.</p>
<p><b>Example 1:</b></p><pre class="crayon-plain-tag">Input: schedule = [[[1,2],[5,6]],[[1,3]],[[4,10]]]
Output: [[3,4]]
Explanation:
There are a total of three employees, and all common
free time intervals would be [-inf, 1], [3, 4], [10, inf].
We discard any intervals that contain inf as they aren't finite.</pre><p><b>Example 2:</b></p><pre class="crayon-plain-tag">Input: schedule = [[[1,3],[6,7]],[[2,4]],[[2,5],[9,12]]]
Output: [[5,6],[7,9]]</pre><p>(Even though we are representing <code>Intervals</code> in the form <code>[x, y]</code>, the objects inside are <code>Intervals</code>, not lists or arrays. For example, <code>schedule[0][0].start = 1, schedule[0][0].end = 2</code>, and <code>schedule[0][0][0]</code> is not defined.)</p>
<p>Also, we wouldn&#8217;t include intervals like [5, 5] in our answer, as they have zero length.</p>
<p><b>Note:</b></p>
<ol>
<li><code>schedule</code> and <code>schedule[i]</code> are lists with lengths in range <code>[1, 50]</code>.</li>
<li><code>0 &lt;= schedule[i].start &lt; schedule[i].end &lt;= 10^8</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"><br />
</ins></p>
<p><strong>Idea:</strong></p>
<p>Merge Intervals (virtually)</p>
<p><img class="alignnone wp-image-1580 size-full" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/759-ep154.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/759-ep154.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/759-ep154-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/01/759-ep154-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p><strong>Solution:</strong></p>
<p>C++</p>
<p>Time complexity: O(nlogn)</p>
<p>Space complexity: O(n)</p>
<p>n is the total number of intervals, n &lt;= 2500</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 81 ms
class Solution {
public:
    vector&lt;Interval&gt; employeeFreeTime(vector&lt;vector&lt;Interval&gt;&gt;&amp; schedule) {
      vector&lt;Interval&gt; all;
      for (const auto intervals : schedule)
        all.insert(all.end(), intervals.begin(), intervals.end());
      std::sort(all.begin(), all.end(), 
                [](const Interval&amp; a, const Interval&amp; b){
                  return a.start &lt; b.start;
                });
      vector&lt;Interval&gt; ans;
      int end = all.front().end;
      for (const Interval&amp; busy : all) {
        if (busy.start &gt; end) 
          ans.emplace_back(end, busy.start);  
        end = max(end, busy.end);
      }
      return ans;
    }
};</pre><p><strong>Related Problems:</strong></p>
<ul>
<li><a href="http://zxi.mytechroad.com/blog/geometry/leetcode-56-merge-intervals/">[解题报告] LeetCode 56. Merge Intervals</a></li>
<li><a href="http://zxi.mytechroad.com/blog/geometry/leetcode-57-insert-interval/">[解题报告] LeetCode 57. Insert Interval</a></li>
<li><a href="http://zxi.mytechroad.com/blog/algorithms/binary-search/leetcode-729-my-calendar-i/">[解题报告] LeetCode 729. My Calendar &#8211; 花花酱</a></li>
<li><a href="http://zxi.mytechroad.com/blog/geometry/leetcode-731-my-calendar-ii/">[解题报告] LeetCode 731. My Calendar II &#8211; 花花酱</a></li>
<li><a href="http://zxi.mytechroad.com/blog/geometry/732-my-calendar-iii/">花花酱 LeetCode 732. My Calendar III</a></li>
</ul>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/geometry/leetcode-759-employee-free-time/">花花酱 LeetCode 759. Employee Free 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/geometry/leetcode-759-employee-free-time/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 752. Open the Lock</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-752-open-the-lock/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-752-open-the-lock/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 25 Dec 2017 17:13:30 +0000</pubDate>
				<category><![CDATA[Hard]]></category>
		<category><![CDATA[Search]]></category>
		<category><![CDATA[BFS]]></category>
		<category><![CDATA[Bidirectional BFS]]></category>
		<category><![CDATA[shortest path]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=1324</guid>

					<description><![CDATA[<p>Problem: You have a lock in front of you with 4 circular wheels. Each wheel has 10 slots: '0', '1', '2', '3', '4', '5', '6', '7',&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-752-open-the-lock/">花花酱 LeetCode 752. Open the Lock</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/M7GgV6TJTdc?feature=oembed" frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen></iframe></p>
<p><strong>Problem:</strong></p>
<div class="question-description">
<p>You have a lock in front of you with 4 circular wheels. Each wheel has 10 slots: <code>'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'</code>. The wheels can rotate freely and wrap around: for example we can turn <code>'9'</code> to be <code>'0'</code>, or <code>'0'</code> to be <code>'9'</code>. Each move consists of turning one wheel one slot.</p>
<p>The lock initially starts at <code>'0000'</code>, a string representing the state of the 4 wheels.</p>
<p>You are given a list of <code>deadends</code> dead ends, meaning if the lock displays any of these codes, the wheels of the lock will stop turning and you will be unable to open it.</p>
<p>Given a <code>target</code> representing the value of the wheels that will unlock the lock, return the minimum total number of turns required to open the lock, or -1 if it is impossible.</p>
<p><b>Example 1:</b></p><pre class="crayon-plain-tag">Input: deadends = ["0201","0101","0102","1212","2002"], target = "0202"
Output: 6
Explanation:
A sequence of valid moves would be "0000" -&gt; "1000" -&gt; "1100" -&gt; "1200" -&gt; "1201" -&gt; "1202" -&gt; "0202".
Note that a sequence like "0000" -&gt; "0001" -&gt; "0002" -&gt; "0102" -&gt; "0202" would be invalid,
because the wheels of the lock become stuck after the display becomes the dead end "0102".</pre><p><b>Example 2:</b></p><pre class="crayon-plain-tag">Input: deadends = ["8888"], target = "0009"
Output: 1
Explanation:
We can turn the last wheel in reverse to move from "0000" -&gt; "0009".</pre><p><b>Example 3:</b></p><pre class="crayon-plain-tag">Input: deadends = ["8887","8889","8878","8898","8788","8988","7888","9888"], target = "8888"
Output: -1
Explanation:
We can't reach the target without getting stuck.</pre><p><b>Example 4:</b></p><pre class="crayon-plain-tag">Input: deadends = [&quot;0000&quot;], target = &quot;8888&quot;
Output: -1</pre><p><b>Note:</b></p>
<ol>
<li>The length of <code>deadends</code> will be in the range <code>[1, 500]</code>.</li>
<li><code>target</code> will not be in the list <code>deadends</code>.</li>
<li>Every string in <code>deadends</code> and the string <code>target</code> will be a string of 4 digits from the 10,000 possibilities <code>'0000'</code> to <code>'9999'</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>题目大意：</p>
<p>给你一个4位密码锁，0可以转到1和9，1可以转到0和2，。。。，9可以转到0和8。</p>
<p>另外给你一些死锁的密码，比如1234，一但转到任何一个死锁的密码，锁就无法再转动了。</p>
<p>给你一个目标密码，问你最少要转多少次才能从0000转到目标密码。</p>
<p><strong>Solution:</strong></p>
<p>C++</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 133 ms
class Solution {
public:
  int openLock(vector&lt;string&gt;&amp; deadends, string target) {
    const string start = "0000";
    unordered_set&lt;string&gt; dead(deadends.begin(), deadends.end());
    if (dead.count(start)) return -1;
    if (start == target) return 0;
    
    queue&lt;string&gt; q;
    unordered_set&lt;string&gt; visited{start};
    
    int steps = 0;
    q.push(start);
    while (!q.empty()) {
      ++steps;
      const int size = q.size();
      for (int i = 0; i &lt; size; ++i) {
        const string curr = q.front(); 
        q.pop();
        for (int i = 0; i &lt; 4; ++i)
          for (int j = -1; j &lt;= 1; j += 2) {
            string next = curr;
            next[i] = (next[i] - '0' + j + 10) % 10 + '0';
            if (next == target) return steps;
            if (dead.count(next) || visited.count(next)) continue; 
            q.push(next);
            visited.insert(next);
          }
      }
    }
    
    return -1;
  }
};</pre><p>C++ / Bidirectional BFS</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 32 ms
class Solution {
public:
  int openLock(vector&lt;string&gt;&amp; deadends, string target) {
    const string start = "0000";
    unordered_set&lt;string&gt; dead(deadends.begin(), deadends.end());
    if (dead.count(start)) return -1;
    if (target == start) return 0;
    
    queue&lt;string&gt; q1;
    queue&lt;string&gt; q2;
    unordered_set&lt;string&gt; v1{start};
    unordered_set&lt;string&gt; v2{target};
    
    int s1 = 0;
    int s2 = 0;
    q1.push(start);
    q2.push(target);
    while (!q1.empty() &amp;&amp; !q2.empty()) {      
      if (!q1.empty()) ++s1;
      const int size = q1.size();
      for (int i = 0; i &lt; size; ++i) {
        const string curr = q1.front(); 
        q1.pop();
        for (int i = 0; i &lt; 4; ++i)
          for (int j = -1; j &lt;= 1; j += 2) {
            string next = curr;
            next[i] = (next[i] - '0' + j + 10) % 10 + '0';
            if (v2.count(next)) return s1 + s2;
            if (dead.count(next) || v1.count(next)) continue; 
            q1.push(next);
            v1.insert(next);
          }
      }
      swap(q1, q2);
      swap(v1, v2);
      swap(s1, s2);
    }
    
    return -1;
  }    
};</pre><p>C++ / Bidirectional BFS / int state / Array</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 9 ms
class Solution {
public:
  int openLock(vector&lt;string&gt;&amp; deadends, string target) {
    constexpr int kMaxN = 10000;
    const vector&lt;int&gt; bases{1, 10, 100, 1000};
    const int start = 0;
    const int goal = stoi(target);
    
    queue&lt;int&gt; q1;
    queue&lt;int&gt; q2;
    vector&lt;int&gt; v1(kMaxN, 0);
    vector&lt;int&gt; v2(kMaxN, 0);  
    for (const string&amp; deadend : deadends)
        v1[stoi(deadend)] = v2[stoi(deadend)] = -1;
    
    if (v1[start] == -1) return -1;
    if (start == goal) return 0;
    
    v1[start] = 1;
    v2[goal] = 1;
    
    int s1 = 0;
    int s2 = 0;
    q1.push(start);
    q2.push(goal);
    while (!q1.empty() &amp;&amp; !q2.empty()) {      
      if (!q1.empty()) ++s1;
      const int size = q1.size();
      for (int i = 0; i &lt; size; ++i) {
        const int curr = q1.front(); 
        q1.pop();
        for (int i = 0; i &lt; 4; ++i) {
          int r = (curr / bases[i]) % 10;
          for (int j = -1; j &lt;= 1; j += 2) {
            const int next = curr + ((r + j + 10) % 10 - r) * bases[i];
            if (v2[next] == 1) return s1 + s2;
            if (v1[next]) continue;            
            q1.push(next);
            v1[next] = 1;
          }
        }
      }
      swap(q1, q2);
      swap(v1, v2);
      swap(s1, s2);
    }    
    return -1;
  }
};</pre><p>Java</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 132 ms
class Solution {
  public int openLock(String[] deadends, String target) {
    String start = "0000";
    Set&lt;String&gt; dead = new HashSet();
    for (String d: deadends) dead.add(d);
    if (dead.contains(start)) return -1;

    Queue&lt;String&gt; queue = new LinkedList();
    queue.offer(start);        

    Set&lt;String&gt; visited = new HashSet();
    visited.add(start);

    int steps = 0;
    while (!queue.isEmpty()) {
      ++steps;
      int size = queue.size();
      for (int s = 0; s &lt; size; ++s) {
        String node = queue.poll();
        for (int i = 0; i &lt; 4; ++i) {
          for (int j = -1; j &lt;= 1; j += 2) {
            char[] chars = node.toCharArray();
            chars[i] = (char)(((chars[i] - '0') + j + 10) % 10 + '0');
            String next = new String(chars);
            if (next.equals(target)) return steps;
            if (dead.contains(next) || visited.contains(next))
                continue;
            visited.add(next);
            queue.offer(next);
          }
        }
      }
    }
    return -1;
  }
}</pre><p>Python</p><pre class="crayon-plain-tag">"""
Author: Huahua
Runtime: 955 ms
"""
class Solution:
    def openLock(self, deadends, target):
        from collections import deque
        deads = set(deadends)
        start = '0000'
        if start in deads: return -1
        q = deque([(start, 0)])        
        visited = set(start)        
        while q:                
            node, step = q.popleft()
            for i in range(0, 4):
                for j in [-1, 1]:
                    nxt = node[:i] + str((int(node[i]) + j + 10) % 10) + node[i+1:]
                    if nxt == target: return step + 1
                    if nxt in deads or nxt in visited: continue
                    q.append((nxt, step + 1))
                    visited.add(nxt)
        return -1</pre><p>Python / Int state</p><pre class="crayon-plain-tag">"""
Author: Huahua
Runtime: 568 ms
"""
class Solution:
    def openLock(self, deadends, target):
        from collections import deque
        bases = [1, 10, 100, 1000]
        deads = set(int(x) for x in deadends)
        start, goal = int('0000'), int(target)        
        if start in deads: return -1
        if start == goal: return 0
        q = deque([(start, 0)])
        visited = set([start])
        while q:   
            node, step = q.popleft()
            for i in range(0, 4):
                r = (node // bases[i]) % 10
                for j in [-1, 1]:
                    nxt = node + ((r + j + 10) % 10 - r) * bases[i]
                    if nxt == goal: return step + 1
                    if nxt in deads or nxt in visited: continue
                    q.append((nxt, step + 1))
                    visited.add(nxt)
        return -1</pre><p>&nbsp;</p>
</div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-752-open-the-lock/">花花酱 LeetCode 752. Open the Lock</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-752-open-the-lock/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 301. Remove Invalid Parentheses</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-301-remove-invalid-parentheses/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-301-remove-invalid-parentheses/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Fri, 22 Dec 2017 00:23:07 +0000</pubDate>
				<category><![CDATA[Hard]]></category>
		<category><![CDATA[Search]]></category>
		<category><![CDATA[String]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[hard]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=1304</guid>

					<description><![CDATA[<p>Problem: Remove the minimum number of invalid parentheses in order to make the input string valid. Return all possible results. Note: The input string may&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-301-remove-invalid-parentheses/">花花酱 LeetCode 301. Remove Invalid Parentheses</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/2k_rS_u6EBk?feature=oembed" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></p>
<p><strong>Problem:</strong></p>
<p>Remove the minimum number of invalid parentheses in order to make the input string valid. Return all possible results.</p>
<p>Note: The input string may contain letters other than the parentheses <code>(</code> and <code>)</code>.</p>
<p><b>Examples:</b></p><pre class="crayon-plain-tag">"()())()" -&gt; ["()()()", "(())()"]
"(a)())()" -&gt; ["(a)()()", "(a())()"]
")(" -&gt; [""]</pre><p>&nbsp;</p>
<p>题目大意：给你一个字符串，由&#8221;(&#8221; &#8220;)&#8221;和其他字符构成。让你删除数量最少的括号使得表达式合法（括号都匹配）。输出所有的合法表达式。</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></p>
<p><strong>Idea:</strong></p>
<p>Search <img class="alignnone size-full wp-image-1317" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/301-ep139-1-1.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/301-ep139-1-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/301-ep139-1-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/301-ep139-1-1-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p><img class="alignnone size-full wp-image-1314" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/301-ep139-2.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/301-ep139-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/301-ep139-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/301-ep139-2-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<h1><strong>Solution: DFS</strong></h1>
<p><div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 0 ms
class Solution {
public:
  vector&lt;string&gt; removeInvalidParentheses(const string&amp; s) {        
    int l = 0;
    int r = 0;

    for (const char ch : s) {
      l += (ch == '(');
      if (l == 0)
        r += (ch == ')');
      else
        l -= (ch == ')');
    }

    vector&lt;string&gt; ans;
    dfs(s, 0, l, r, ans);
    return ans;
  }
private:
  bool isValid(const string&amp; s) {
    int count = 0;
    for (const char ch : s) {
      if (ch == '(') ++count;
      if (ch == ')') --count;
      if (count &lt; 0) return false;
    }
    return count == 0;
  }

  // l/r: number of left/right parentheses to remove.
  void dfs(const string&amp; s, int start, int l, int r, vector&lt;string&gt;&amp; ans) {
    // Nothing to remove.
    if (l == 0 &amp;&amp; r == 0) {
      if (isValid(s)) ans.push_back(s);
      return;
    }

    for (int i = start; i &lt; s.length(); ++i) {
      // We only remove the first parenthes if there are consecutive ones to avoid duplications.
      if (i != start &amp;&amp; s[i] == s[i - 1]) continue;

      if (s[i] == '(' || s[i] == ')') {
        string curr = s;
        curr.erase(i, 1);
        if (r &gt; 0 &amp;&amp; s[i] == ')') 
          dfs(curr, i, l, r - 1, ans);
        else if (l &gt; 0 &amp;&amp; s[i] == '(')
          dfs(curr, i, l - 1, r, ans);
      }
    }
  }
};</pre><p></div></div></p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-301-remove-invalid-parentheses/">花花酱 LeetCode 301. Remove Invalid Parentheses</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-301-remove-invalid-parentheses/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 164. Maximum Gap</title>
		<link>https://zxi.mytechroad.com/blog/difficulty/hard/leetcode-164-maximum-gap/</link>
					<comments>https://zxi.mytechroad.com/blog/difficulty/hard/leetcode-164-maximum-gap/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 11 Dec 2017 00:19:22 +0000</pubDate>
				<category><![CDATA[Array]]></category>
		<category><![CDATA[Hard]]></category>
		<category><![CDATA[bucket]]></category>
		<category><![CDATA[sorting]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=1173</guid>

					<description><![CDATA[<p>https://leetcode.com/problems/maximum-gap/description/ Problem: Given an unsorted array, find the maximum difference between the successive elements in its sorted form. Try to solve it in linear time/space.&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/difficulty/hard/leetcode-164-maximum-gap/">花花酱 LeetCode 164. Maximum Gap</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><a href="https://leetcode.com/problems/maximum-gap/description/">https://leetcode.com/problems/maximum-gap/description/</a></p>
<p><strong>Problem:</strong></p>
<p>Given an unsorted array, find the maximum difference between the successive elements in its sorted form.</p>
<p>Try to solve it in linear time/space.</p>
<p>Return 0 if the array contains less than 2 elements.</p>
<p>You may assume all elements in the array are non-negative integers and fit in the 32-bit signed integer range.</p>
<p>题目大意:</p>
<p>给你一个没有排序的正整数数组。输出排序后，相邻元素的差的最大值(Max Gap)。需要在线性时间内解决。</p>
<p><strong>Example:</strong></p>
<p><span style="font-weight: 400;">Input:  [5, 0, 4, 2, 12, 10]</span></p>
<p>Output: 5</p>
<p><strong>Explanation: </strong></p>
<p><span style="font-weight: 400;">Sorted: [0, 2, 4, 5, 10, 12]</span></p>
<p>max gap is 10 &#8211; 5 = 5</p>
<p><strong>Idea:</strong></p>
<p>Bucket sort. Use n buckets to store all the numbers. For each bucket, only track the min / max value.</p>
<p>桶排序。用n个桶来存放数字。对于每个桶，只跟踪存储最大值和最小值。</p>
<p>max gap must come from two &#8220;adjacent&#8221; buckets, b[i], b[j], j &gt; i, b[i+1] &#8230; b[j &#8211; 1] must be empty.</p>
<p>max gap 只可能来自&#8221;相邻&#8221;的两个桶 b[i] 和 b[j], j &gt; i, b[i] 和 b[j] 之间的桶（如果有）必须为空。</p>
<p>max gap = b[j].min &#8211; b[i].min</p>
<p>Time complexity: O(n)</p>
<p>时间复杂度: O(n)</p>
<p>Space complexity: O(n)</p>
<p>空间复杂度: O(n)</p>
<p><strong>Solution:</strong></p>
<p>C++</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 6 ms
class Solution {
public:
    int maximumGap(vector&lt;int&gt;&amp; nums) {
        const int n = nums.size();
        if (n &lt;= 1) return 0;
        
        const auto mm = minmax_element(nums.begin(), nums.end());
        const int range = *mm.second - *mm.first;
        const int bin_size = range / n + 1;
        vector&lt;int&gt; min_vals(n, INT_MAX);
        vector&lt;int&gt; max_vals(n, INT_MIN);
        for (const int num : nums) {
            const int index = (num - *mm.first) / bin_size;
            min_vals[index] = min(min_vals[index], num);
            max_vals[index] = max(max_vals[index], num);
        }
        
        int max_gap = 0;
        int prev_max = max_vals[0];
        for (int i = 1; i &lt; n; ++i) {
            if (min_vals[i] != INT_MAX) {
                max_gap = max(max_gap, min_vals[i] - prev_max);
                prev_max = max_vals[i];
            }
        }
        return max_gap;
    }
};</pre><p>&nbsp;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/difficulty/hard/leetcode-164-maximum-gap/">花花酱 LeetCode 164. Maximum Gap</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/hard/leetcode-164-maximum-gap/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 732. My Calendar III</title>
		<link>https://zxi.mytechroad.com/blog/geometry/732-my-calendar-iii/</link>
					<comments>https://zxi.mytechroad.com/blog/geometry/732-my-calendar-iii/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Thu, 07 Dec 2017 05:29:41 +0000</pubDate>
				<category><![CDATA[Geometry]]></category>
		<category><![CDATA[Hard]]></category>
		<category><![CDATA[geometry]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[ordered map]]></category>
		<category><![CDATA[range]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=1131</guid>

					<description><![CDATA[<p>Problem: link: https://leetcode.com/problems/my-calendar-iii/description/ Implement a MyCalendarThree class to store your events. A new event can always be added. Your class will have one method, book(int start, int end). Formally, this represents&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/geometry/732-my-calendar-iii/">花花酱 LeetCode 732. My Calendar III</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/yK9a-rT3FBQ?feature=oembed" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></p>
<p><strong>Problem:</strong></p>
<p>link: <a href="https://leetcode.com/problems/my-calendar-iii/description/">https://leetcode.com/problems/my-calendar-iii/description/</a></p>
<p>Implement a <code>MyCalendarThree</code> class to store your events. A new event can <b>always</b> be added.</p>
<p>Your class will have one method, <code>book(int start, int end)</code>. Formally, this represents a booking on the half open interval <code>[start, end)</code>, the range of real numbers <code>x</code> such that <code>start &lt;= x &lt; end</code>.</p>
<p>A <i>K-booking</i> happens when <b>K</b> events have some non-empty intersection (ie., there is some time that is common to all K events.)</p>
<p>For each call to the method <code>MyCalendar.book</code>, return an integer <code>K</code> representing the largest integer such that there exists a <code>K</code>-booking in the calendar.</p>
<p>Your class will be called like this: <code>MyCalendarThree cal = new MyCalendarThree();</code><code>MyCalendarThree.book(start, end)</code></p>
<p><b>Example 1:</b></p>
<pre class="crayon:false">MyCalendarThree();
MyCalendarThree.book(10, 20); // returns 1
MyCalendarThree.book(50, 60); // returns 1
MyCalendarThree.book(10, 40); // returns 2
MyCalendarThree.book(5, 15); // returns 3
MyCalendarThree.book(5, 10); // returns 3
MyCalendarThree.book(25, 55); // returns 3
Explanation<b>:</b> 
The first two events can be booked and are disjoint, so the maximum K-booking is a 1-booking.
The third event [10, 40) intersects the first event, and the maximum K-booking is a 2-booking.
The remaining events cause the maximum K-booking to be only a 3-booking.
Note that the last event locally causes a 2-booking, but the answer is still 3 because
eg. [10, 20), [10, 40), and [5, 15) are still triple booked.
</pre>
<p><b>Note:</b></p>
<ul>
<li>The number of calls to <code>MyCalendarThree.book</code> per test case will be at most <code>400</code>.</li>
<li>In calls to <code>MyCalendarThree.book(start, end)</code>, <code>start</code> and <code>end</code> are integers in the range <code>[0, 10^9]</code>.</li>
</ul>
<p><strong>Idea:</strong></p>
<p>Similar to <a href="http://zxi.mytechroad.com/blog/geometry/leetcode-731-my-calendar-ii/">LeetCode 731 My Calendar II</a> Use an ordered / tree map to track the number of event at current time.</p>
<p>For a new book event, increase the number of events at start, decrease the number of events at end.</p>
<p>Scan the timeline to find the maximum number of events.</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></p>
<p><img class="alignnone size-large wp-image-4040" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/732-ep126-1.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/732-ep126-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/732-ep126-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/732-ep126-1-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p><img class="alignnone size-large wp-image-4039" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/732-ep126-2.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/732-ep126-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/732-ep126-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/732-ep126-2-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p><img class="alignnone size-full wp-image-4038" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/732-ep126-3.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/732-ep126-3.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/732-ep126-3-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/732-ep126-3-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<h1><strong>Solution 1: Count Boundaries</strong></h1>
<p>Time complexity: O(n^2)</p>
<p>Space complexity: O(n)</p>
<p><div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 116 ms
class MyCalendarThree {
public:
    MyCalendarThree() {}
    
    int book(int start, int end) {
        ++deltas_[start];
        --deltas_[end];
        int ans = 0;
        int curr = 0;
        for (const auto&amp; kv : deltas_)            
            ans = max(ans, curr += kv.second);
        return ans;
    }
private:
    map&lt;int, int&gt; deltas_;
};</pre><p></div></div></p>
<h1><strong>Solution 2</strong></h1>
<p><div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 66 ms
class MyCalendarThree {
public:
    MyCalendarThree() {
        counts_[INT_MIN] = 0;
        counts_[INT_MAX] = 0;
        max_count_ = 0;
    }
    
    int book(int start, int end) {        
        auto l = prev(counts_.upper_bound(start));   // l-&gt;first &lt; start
        auto r = counts_.lower_bound(end);           // r-&gt;first &gt;= end
        for (auto curr = l, next = curr; curr != r; curr = next) {
            ++next;
            
            if (next-&gt;first &gt; end)
                counts_[end] = curr-&gt;second;
            
            if (curr-&gt;first &lt;= start &amp;&amp; next-&gt;first &gt; start)
                max_count_ = max(max_count_, counts_[start] = curr-&gt;second + 1);            
            else
                max_count_ = max(max_count_, ++curr-&gt;second);
        }
        
        return max_count_;
    }
private:
    map&lt;int, int&gt; counts_;
    int max_count_;
};</pre><p></div></div></p>
<h1><strong>Solution 3: Segment Tree</strong></h1>
<p><div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 63 ms (&lt;95.65%)
class MyCalendarThree {
public:
    MyCalendarThree(): max_count_(0) {
        root_.reset(new Node(0, 100000000, 0));        
    }
    
    int book(int start, int end) {
        Add(start, end, root_.get());
        return max_count_;
    }
private:
    struct Node {
        Node(int l, int r, int count):l(l), m(-1), r(r), count(count){}
        int l;
        int m;
        int r;
        int count;
        std::unique_ptr&lt;Node&gt; left;
        std::unique_ptr&lt;Node&gt; right;
    };
    
    void Add(int start, int end, Node* root) {
        if (root-&gt;m != -1) {
            if (end &lt;= root-&gt;m) 
                Add(start, end, root-&gt;left.get());
            else if(start &gt;= root-&gt;m)
                Add(start, end, root-&gt;right.get());
            else {
                Add(start, root-&gt;m, root-&gt;left.get());
                Add(root-&gt;m, end, root-&gt;right.get());
            }
            return;
        }
        
        if (start == root-&gt;l &amp;&amp; end == root-&gt;r)
            max_count_ = max(max_count_, ++root-&gt;count);
        else if (start == root-&gt;l) {
            root-&gt;m = end;
            root-&gt;left.reset(new Node(start, root-&gt;m, root-&gt;count + 1));
            root-&gt;right.reset(new Node(root-&gt;m, root-&gt;r, root-&gt;count));
            max_count_ = max(max_count_, root-&gt;count + 1);
        } else if(end == root-&gt;r) {
            root-&gt;m = start;
            root-&gt;left.reset(new Node(root-&gt;l, root-&gt;m, root-&gt;count));
            root-&gt;right.reset(new Node(root-&gt;m, root-&gt;r, root-&gt;count + 1));
            max_count_ = max(max_count_, root-&gt;count + 1);
        } else {
            root-&gt;m = start;
            root-&gt;left.reset(new Node(root-&gt;l, root-&gt;m, root-&gt;count));
            root-&gt;right.reset(new Node(root-&gt;m, root-&gt;r, root-&gt;count));
            Add(start, end, root-&gt;right.get());
        }
    }
    
    std::unique_ptr&lt;Node&gt; root_;
    int max_count_;
};</pre><p></div><h2 class="tabtitle">Python3</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">"""
Author: Huahua
Runtime: 436 ms (&lt;88.88%)
"""
class Node:
    def __init__(self, l, r, count):
        self.l = l
        self.m = -1
        self.r = r            
        self.count = count
        self.left = None
        self.right = None
            
class MyCalendarThree:        
    def __init__(self):
        self.root = Node(0, 10**9, 0)
        self.max = 0

    def book(self, start, end):
        self.add(start, end, self.root)
        return self.max
    
    def add(self, start, end, root):
        if root.m != -1:
            if end &lt;= root.m: self.add(start, end, root.left)
            elif start &gt;= root.m: self.add(start, end, root.right)
            else:
                self.add(start, root.m, root.left)
                self.add(root.m, end, root.right)
            return
        
        if start == root.l and end == root.r:
            root.count += 1
            self.max = max(self.max, root.count)
        elif start == root.l:
            root.m = end
            root.left = Node(start, root.m, root.count + 1)
            root.right = Node(root.m, root.r, root.count)
            self.max = max(self.max, root.count + 1)
        elif end == root.r:
            root.m = start;
            root.left = Node(root.l, root.m, root.count)
            root.right = Node(root.m, root.r, root.count + 1)
            self.max = max(self.max, root.count + 1)
        else:
            root.m = start
            root.left = Node(root.l, root.m, root.count)
            root.right = Node(root.m, root.r, root.count)
            self.add(start, end, root.right)</pre><p></div></div></p>
<p><strong>Related Problems:</strong></p>
<ul>
<li><a href="http://zxi.mytechroad.com/blog/binary-search/leetcode-729-my-calendar-i/">[解题报告] LeetCode 729. My Calendar I</a></li>
<li><a href="http://zxi.mytechroad.com/blog/geometry/leetcode-731-my-calendar-ii/">[解题报告] LeetCode 731. My Calendar II</a></li>
</ul>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/geometry/732-my-calendar-iii/">花花酱 LeetCode 732. My Calendar III</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/geometry/732-my-calendar-iii/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 312. Burst Balloons</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-312-burst-balloons/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-312-burst-balloons/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 27 Nov 2017 16:42:23 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[Hard]]></category>
		<category><![CDATA[dp]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=933</guid>

					<description><![CDATA[<p>Problem: Given&#160;n&#160;balloons, indexed from&#160;0&#160;to&#160;n-1. Each balloon is painted with a number on it represented by array&#160;nums. You are asked to burst all the balloons. If&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-312-burst-balloons/">花花酱 LeetCode 312. Burst Balloons</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-4-3 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe width="500" height="375" src="https://www.youtube.com/embed/z3hu2Be92UA?feature=oembed" frameborder="0" gesture="media" allowfullscreen></iframe>
</div></figure>



<p><strong>Problem:</strong></p>



<p>Given&nbsp;<code>n</code>&nbsp;balloons, indexed from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>n-1</code>. Each balloon is painted with a number on it represented by array&nbsp;<code>nums</code>. You are asked to burst all the balloons. If the you burst balloon&nbsp;<code>i</code>&nbsp;you will get&nbsp;<code>nums[left] * nums[i] * nums[right]</code>&nbsp;coins. Here&nbsp;<code>left</code>&nbsp;and&nbsp;<code>right</code>&nbsp;are adjacent indices of&nbsp;<code>i</code>. After the burst, the&nbsp;<code>left</code>&nbsp;and&nbsp;<code>right</code>then becomes adjacent.</p>



<p>Find the maximum coins you can collect by bursting the balloons wisely.</p>



<p><b>Note:</b><br>
(1) You may imagine&nbsp;<code>nums[-1] = nums[n] = 1</code>. They are not real therefore you can not burst them.<br>
(2) 0 ≤&nbsp;<code>n</code>&nbsp;≤ 500, 0 ≤&nbsp;<code>nums[i]</code>&nbsp;≤ 100</p>



<p><b>Example:</b></p>



<p>Given&nbsp;<code>[3, 1, 5, 8]</code></p>



<p>Return&nbsp;<code>167</code>
</p>



<pre class="crayon-plain-tag">nums = [3,1,5,8] --&gt; [3,5,8] --&gt;   [3,8]   --&gt;  [8]  --&gt; []
   coins =  3*1*5      +  3*5*8    +  1*3*8      + 1*8*1   = 167</pre>



<p><strong>Idea</strong></p>



<p>DP</p>



<p><strong>Solution1:</strong></p>



<p>C++ / Recursion with memoization
</p>



<pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 16 ms
class Solution {
public:
    int maxCoins(vector&lt;int&gt;&amp; nums) {
        int n = nums.size();
        nums.insert(nums.begin(), 1);
        nums.push_back(1);
        
        // c[i][j] = maxCoins(nums[i:j+1])
        c_ = vector&lt;vector&lt;int&gt;&gt;(n+2, vector&lt;int&gt;(n+2, 0));
        
        return maxCoins(nums, 1, n);
    }
private:
    int maxCoins(const vector&lt;int&gt;&amp; nums, const int i, const int j) {
        if(i&gt;j) return 0;
        if(c_[i][j]&gt;0) return c_[i][j];
        
        if(i==j) return nums[i-1]*nums[i]*nums[i+1];
        
        int ans=0;
        for(int k=i;k&lt;=j;++k)
             ans=max(ans, maxCoins(nums,i,k-1) + nums[i-1]*nums[k]*nums[j+1] + maxCoins(nums, k+1, j));
        
        c_[i][j] = ans;
        
        return c_[i][j];
    }
    
    vector&lt;vector&lt;int&gt;&gt; c_;
};</pre>



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

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
  private int[][] memo;
  private int[] vals;
  public int maxCoins(int[] nums) {
    final int n = nums.length;
    vals = new int[n + 2];
    for (int i = 0; i &lt; n; ++i) vals[i + 1] = nums[i];
    vals[0] = vals[n + 1] = 1;
    memo = new int[n + 2][n + 2];
    return maxCoins(1, n);
  }
  
  private int maxCoins(int i, int j) {
    if (i &gt; j) return 0;
    if (i == j) return vals[i - 1] * vals[i] * vals[i + 1];
    if (memo[i][j] &gt; 0) return memo[i][j];
    int ans = 0;
    for (int k = i; k &lt;= j; ++k)
      ans = Math.max(ans, maxCoins(i, k - 1) + vals[i - 1] * vals[k] * vals[j + 1] + maxCoins(k + 1, j));
    memo[i][j] = ans;
    return memo[i][j];
  }
}</pre>
</div></div>



<p><strong>Solution2:</strong></p>



<p>C++&nbsp; / DP
</p>



<pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 9 ms
class Solution {
public:
    int maxCoins(vector&lt;int&gt;&amp; nums) {
        int n = nums.size();
        nums.insert(nums.begin(), 1);
        nums.push_back(1);
        
        // c[i][j] = maxCoins(nums[i:j+1])
        vector&lt;vector&lt;int&gt;&gt; c(n+2, vector&lt;int&gt;(n+2, 0));
        
        for(int l=1;l&lt;=n;++l)
            for(int i=1;i&lt;=n-l+1;++i) {
                int j=i+l-1;
                for(int k=i;k&lt;=j;++k) {
                    c[i][j] = max(c[i][j], c[i][k-1] + nums[i-1]*nums[k]*nums[j+1] + c[k+1][j]);
                }
            }
        
        return c[1][n];
    }
};</pre>



<p>Java / DP</p>



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

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
  public int maxCoins(int[] nums) {
    final int n = nums.length;
    int[] vals = new int[n + 2];
    for (int i = 0; i &lt; n; ++i) vals[i + 1] = nums[i];
    vals[0] = vals[n + 1] = 1;
    int[][] dp = new int[n + 2][n + 2];
    for (int l = 1; l &lt;= n; ++l)
      for (int i = 1; i + l &lt;= n + 1; ++i) {
        int j = i + l - 1;
        int best = 0;
        for (int k = i; k &lt;= j; ++k)
          best = Math.max(best, 
                          dp[i][k - 1] + vals[i - 1] * vals[k] * vals[j + 1] + dp[k + 1][j]);
        dp[i][j] = best;
      }
    return dp[1][n];        
  }
}</pre>
</div></div>



<p><br></p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-312-burst-balloons/">花花酱 LeetCode 312. Burst Balloons</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-312-burst-balloons/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 639. Decode Ways II</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-639-decode-ways-ii/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-639-decode-ways-ii/#comments</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 19 Nov 2017 03:53:39 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[Hard]]></category>
		<category><![CDATA[counting]]></category>
		<category><![CDATA[decode]]></category>
		<category><![CDATA[string]]></category>
		<category><![CDATA[ways]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=831</guid>

					<description><![CDATA[<p>Problem: A message containing letters from A-Z is being encoded to numbers using the following mapping way: [crayon-665bb3dad6395916396390/] Beyond that, now the encoded string can also contain&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-639-decode-ways-ii/">花花酱 LeetCode 639. Decode Ways 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/65j9zS-YWZo?feature=oembed" frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen></iframe></p>
<p><strong>Problem:</strong></p>
<p>A message containing letters from <code>A-Z</code> is being encoded to numbers using the following mapping way:</p><pre class="crayon-plain-tag">'A' -&gt; 1
'B' -&gt; 2
...
'Z' -&gt; 26</pre><p>Beyond that, now the encoded string can also contain the character &#8216;*&#8217;, which can be treated as one of the numbers from 1 to 9.</p>
<p>Given the encoded message containing digits and the character &#8216;*&#8217;, return the total number of ways to decode it.</p>
<p>Also, since the answer may be very large, you should return the output mod 10<sup>9</sup> + 7.</p>
<p><b>Example 1:</b></p><pre class="crayon-plain-tag">Input: &quot;*&quot;
Output: 9
Explanation: The encoded message can be decoded to the string:
&quot;A&quot;, &quot;B&quot;, &quot;C&quot;, &quot;D&quot;, &quot;E&quot;, &quot;F&quot;, &quot;G&quot;, &quot;H&quot;, &quot;I&quot;.</pre><p><b>Example 2:</b></p><pre class="crayon-plain-tag">Input: &quot;1*&quot;
Output: 9 + 9 = 18</pre><p><b>Note:</b></p>
<ol>
<li>The length of the input string will fit in range [1, 10<sup>5</sup>].</li>
<li>The input string will only contain the character &#8216;*&#8217; and digits &#8216;0&#8217; &#8211; &#8216;9&#8217;.</li>
</ol>
<p><strong>Idea:</strong></p>
<p>DP</p>
<p>Time complexity: O(n)</p>
<p>Space complexity: O(1)</p>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/639-ep110-1-1.png"><img class="alignnone wp-image-843 size-full" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/639-ep110-1-1.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/639-ep110-1-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/639-ep110-1-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/639-ep110-1-1-768x432.png 768w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/639-ep110-1-1-624x351.png 624w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/639-ep110-2.png"><img class="alignnone size-full wp-image-836" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/639-ep110-2.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/639-ep110-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/639-ep110-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/639-ep110-2-768x432.png 768w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/639-ep110-2-624x351.png 624w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<p><strong>Solution:</strong></p>
<p>C++</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 58 ms
class Solution {
public:
    int numDecodings(string s) {
        if (s.empty()) return 0;        
        //           dp[-1]  dp[0]
        long dp[2] = {1, ways(s[0])};
        for (int i = 1; i &lt; s.length(); ++i) {
            long dp_i = ways(s[i]) * dp[1] + ways(s[i - 1], s[i]) * dp[0];
            dp_i %= kMod;
            dp[0] = dp[1];
            dp[1] = dp_i;
        }
        return dp[1];
    }
private:
    static constexpr int kMod = 1000000007;    
    
    int ways(char c) {
        if (c == '0') return 0;
        if (c == '*') return 9;
        return 1;
    }
    
    int ways(char c1, char c2) {
        if (c1 == '*' &amp;&amp; c2 == '*') 
            return 15;
        if (c1 == '*') {
          return (c2 &gt;= '0' &amp;&amp; c2 &lt;= '6') ? 2 : 1;
        } else if (c2 == '*') {
            switch (c1) {
                case '1': return 9;
                case '2': return 6;
                default: return 0;
            }
        } else {
            int prefix = (c1 - '0') * 10 + (c2 - '0');
            return prefix &gt;= 10 &amp;&amp; prefix &lt;= 26;
        }        
    }
};</pre><p>&nbsp;</p>
<p><strong>Related Problems:</strong></p>
<ul>
<li><a href="http://zxi.mytechroad.com/blog/dynamic-programming/leetcode-91-decode-ways/">[解题报告] LeetCode 91. Decode Ways</a></li>
</ul>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-639-decode-ways-ii/">花花酱 LeetCode 639. Decode Ways 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/dynamic-programming/leetcode-639-decode-ways-ii/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 726. Number of Atoms</title>
		<link>https://zxi.mytechroad.com/blog/string/leetcode-726-number-of-atoms/</link>
					<comments>https://zxi.mytechroad.com/blog/string/leetcode-726-number-of-atoms/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Thu, 16 Nov 2017 06:09:20 +0000</pubDate>
				<category><![CDATA[Hard]]></category>
		<category><![CDATA[Recursion]]></category>
		<category><![CDATA[String]]></category>
		<category><![CDATA[DFS]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=810</guid>

					<description><![CDATA[<p>&#160; Problem: Given a chemical formula (given as a string), return the count of each atom. An atomic element always starts with an uppercase character, then zero&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/string/leetcode-726-number-of-atoms/">花花酱 LeetCode 726. Number of Atoms</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>&nbsp;</p>
<div class="question-description">
<p><iframe width="500" height="375" src="https://www.youtube.com/embed/6nQ2jfs7a7I?feature=oembed" frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen></iframe></p>
<p><strong>Problem:</strong></p>
<p>Given a chemical <code>formula</code> (given as a string), return the count of each atom.</p>
<p>An atomic element always starts with an uppercase character, then zero or more lowercase letters, representing the name.</p>
<p>1 or more digits representing the count of that element may follow if the count is greater than 1. If the count is 1, no digits will follow. For example, H2O and H2O2 are possible, but H1O2 is impossible.</p>
<p>Two formulas concatenated together produce another formula. For example, H2O2He3Mg4 is also a formula.</p>
<p>A formula placed in parentheses, and a count (optionally added) is also a formula. For example, (H2O2) and (H2O2)3 are formulas.</p>
<p>Given a formula, output the count of all elements as a string in the following form: the first name (in sorted order), followed by its count (if that count is more than 1), followed by the second name (in sorted order), followed by its count (if that count is more than 1), and so on.</p>
<p><b>Example 1:</b></p><pre class="crayon-plain-tag">Input: 
formula = "H2O"
Output: "H2O"
Explanation: 
The count of elements are {'H': 2, 'O': 1}.</pre><p><b>Example 2:</b></p><pre class="crayon-plain-tag">Input: 
formula = &quot;Mg(OH)2&quot;
Output: &quot;H2MgO2&quot;
Explanation: 
The count of elements are {'H': 2, 'Mg': 1, 'O': 2}.</pre><p><b>Example 3:</b></p><pre class="crayon-plain-tag">Input: 
formula = &quot;K4(ON(SO3)2)2&quot;
Output: &quot;K4N2O14S4&quot;
Explanation: 
The count of elements are {'K': 4, 'N': 2, 'O': 14, 'S': 4}.</pre><p><b>Note:</b></p>
<ul>
<li>All atom names consist of lowercase letters, except for the first character which is uppercase.</li>
<li>The length of <code>formula</code> will be in the range <code>[1, 1000]</code>.</li>
<li><code>formula</code> will only consist of letters, digits, and round parentheses, and is a valid formula as defined in the problem.</li>
</ul>
<p>&nbsp;</p>
<p><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script><br />
<ins class="adsbygoogle" style="display: block; text-align: center;" data-ad-layout="in-article" data-ad-format="fluid" data-ad-client="ca-pub-2404451723245401" data-ad-slot="7983117522"></ins><br />
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></p>
<p><strong>Idea:</strong></p>
<p>Recursion</p>
<p>Time complexity: O(n)</p>
<p>Space complexity: O(n)</p>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/726-ep108.png"><img class="alignnone size-full wp-image-815" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/726-ep108.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/726-ep108.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/726-ep108-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/726-ep108-768x432.png 768w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/726-ep108-624x351.png 624w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
</div>
<p><strong>Solution:</strong></p>
<p>C++</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 3 ms
class Solution {
public:
    string countOfAtoms(const string&amp; formula) {
        int i = 0;
        string ans;
        for (const auto&amp; kv : countOfAtoms(formula, i)) {
            ans += kv.first;
            if (kv.second &gt; 1) ans += std::to_string(kv.second);
        }
        return ans;
    }
private:    
    map&lt;string, int&gt; countOfAtoms(const string&amp; formula, int&amp; i) {
        map&lt;string, int&gt; counts;
        while (i != formula.length()) {
            if (formula[i] == '(') {                
                const auto&amp; tmp_counts = countOfAtoms(formula, ++i);
                const int count = getCount(formula, i);
                for (const auto&amp; kv : tmp_counts)
                    counts[kv.first] += kv.second * count;
            } else if (formula[i] == ')') {
                ++i;
                return counts;
            } else {
                const string&amp; name = getName(formula, i);
                counts[name] += getCount(formula, i);
            }
        }
        return counts;
    }
    
    string getName(const string&amp; formula, int&amp; i) {
        string name;
        while (isalpha(formula[i]) 
           &amp;&amp; (name.empty() || islower(formula[i]))) name += formula[i++];
        return name;
    }
    
    int getCount(const string&amp; formula, int&amp; i) {
        string count_str;
        while (isdigit(formula[i])) count_str += formula[i++];
        return count_str.empty() ? 1 : std::stoi(count_str);
    }    
};</pre><p>&nbsp;</p>
<p>Java</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 13 ms
class Solution {
    private int i;    
    public String countOfAtoms(String formula) {
        StringBuilder ans = new StringBuilder();
        i = 0;
        Map&lt;String, Integer&gt; counts = countOfAtoms(formula.toCharArray());
        for (String name: counts.keySet()) {
            ans.append(name);
            int count = counts.get(name);
            if (count &gt; 1) ans.append("" + count);
        }
        return ans.toString();
    }
    
    private Map&lt;String, Integer&gt; countOfAtoms(char[] f) {
        Map&lt;String, Integer&gt; ans = new TreeMap&lt;String, Integer&gt;();
        while (i != f.length) {
            if (f[i] == '(') {
                ++i;
                Map&lt;String, Integer&gt; tmp = countOfAtoms(f);
                int count = getCount(f);
                for (Map.Entry&lt;String, Integer&gt; entry : tmp.entrySet())
                    ans.put(entry.getKey(), 
                            ans.getOrDefault(entry.getKey(), 0) 
                            + entry.getValue() * count);
            } else if (f[i] == ')') {
                ++i;
                return ans;
            } else {
                String name = getName(f);
                ans.put(name, ans.getOrDefault(name, 0) + getCount(f));
            }
        }
        return ans;
    }
    
    private String getName(char[] f) {
        String name = "" + f[i++];
        while (i &lt; f.length &amp;&amp; 'a' &lt;= f[i] &amp;&amp; f[i] &lt;= 'z') name += f[i++];
        return name;
    }
    
    private int getCount(char[] f) {
        int count = 0;
        while (i &lt; f.length &amp;&amp; '0' &lt;= f[i] &amp;&amp; f[i] &lt;= '9') {
            count = count * 10 + (f[i] - '0');
            ++i;
        }
        return count == 0 ? 1 : count;
    }
}</pre><p>&nbsp;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/string/leetcode-726-number-of-atoms/">花花酱 LeetCode 726. Number of Atoms</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-726-number-of-atoms/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 321. Create Maximum Number</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-321-create-maximum-number/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-321-create-maximum-number/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Tue, 14 Nov 2017 16:21:18 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[Greedy]]></category>
		<category><![CDATA[Hard]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[greedy]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[max number]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=796</guid>

					<description><![CDATA[<p>Problem: Given two arrays of length m and n with digits 0-9 representing two numbers. Create the maximum number of length k &#60;= m + n from digits of the two. The relative&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-321-create-maximum-number/">花花酱 LeetCode 321. Create Maximum Number</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/YYduNJfzWaA?feature=oembed" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></p>
<p><strong>Problem:</strong></p>
<p>Given two arrays of length <code>m</code> and <code>n</code> with digits <code>0-9</code> representing two numbers. Create the maximum number of length <code>k &lt;= m + n</code> from digits of the two. The relative order of the digits from the same array must be preserved. Return an array of the <code>k</code> digits. You should try to optimize your time and space complexity.</p>
<p><b>Example 1:</b></p>
<p>nums1 = <code>[3, 4, 6, 5]</code><br />
nums2 = <code>[9, 1, 2, 5, 8, 3]</code><br />
k = <code>5</code><br />
return <code>[9, 8, 6, 5, 3]</code></p>
<p><b>Example 2:</b></p>
<p>nums1 = <code>[6, 7]</code><br />
nums2 = <code>[6, 0, 4]</code><br />
k = <code>5</code><br />
return <code>[6, 7, 6, 0, 4]</code></p>
<p><b>Example 3:</b></p>
<p>nums1 = <code>[3, 9]</code><br />
nums2 = <code>[8, 9]</code><br />
k = <code>3</code><br />
return <code>[9, 8, 9]</code></p>
<p><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script><br />
<ins class="adsbygoogle" style="display: block; text-align: center;" data-ad-layout="in-article" data-ad-format="fluid" data-ad-client="ca-pub-2404451723245401" data-ad-slot="7983117522"></ins><br />
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></p>
<p>题目大意：给你两个数字数组和k，返回从两个数组中选取k个数字能够组成的最大值。</p>
<h1><strong>Idea: </strong>Greedy + DP</h1>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/321-ep107-2.png"><img class="alignnone wp-image-804 size-full" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/321-ep107-2.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/321-ep107-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/321-ep107-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/321-ep107-2-768x432.png 768w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/321-ep107-2-624x351.png 624w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<h1><strong>Solution:</strong></h1>
<p>Time complexity: O(k * (n1+n2)^2)</p>
<p>Space complexity: O(n1+n2)</p>
<p><div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 26 ms
class Solution {
public:
    vector&lt;int&gt; maxNumber(vector&lt;int&gt;&amp; nums1, vector&lt;int&gt;&amp; nums2, int k) {
        vector&lt;int&gt; ans;
        const int n1 = nums1.size();
        const int n2 = nums2.size();
        for (int i = max(0, k - n2); i &lt;= min(k, n1); ++i)
            ans = max(ans, maxNumber(maxNumber(nums1, i), 
                                     maxNumber(nums2, k - i)));
        return ans;
    }
private:    
    vector&lt;int&gt; maxNumber(const vector&lt;int&gt;&amp; nums, int k) {
        vector&lt;int&gt; ans(k);                
        int j = 0;
        for (int i = 0; i &lt; nums.size(); ++i) {
            while (j &gt; 0 &amp;&amp; nums[i] &gt; ans[j - 1] 
                   &amp;&amp; nums.size() - i &gt; k - j) --j;
            if (j &lt; k) ans[j++] = nums[i];
        }
        return ans;
    }
    
    vector&lt;int&gt; maxNumber(const vector&lt;int&gt;&amp; nums1, const vector&lt;int&gt;&amp; nums2) {
        vector&lt;int&gt; ans(nums1.size() + nums2.size());
        auto s1 = nums1.cbegin();
        auto e1 = nums1.cend();
        auto s2 = nums2.cbegin();
        auto e2 = nums2.cend();        
        int index = 0;
        while (s1 != e1 || s2 != e2)
            ans[index++] = 
              lexicographical_compare(s1, e1, s2, e2) ? *s2++ : *s1++;
        return ans;
    }
};</pre><p></div><h2 class="tabtitle">Java</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 18 ms
class Solution {
    public int[] maxNumber(int[] nums1, int[] nums2, int k) {
        int[] best = new int[0];
        for (int i = Math.max(0, k - nums2.length); 
                 i &lt;= Math.min(k, nums1.length); ++i)            
            best = max(best, 0, 
                       maxNumber(maxNumber(nums1, i), 
                                 maxNumber(nums2, k - i)), 0);
        return best;
    }
    
    private int[] maxNumber(int[] nums, int k) {
        int[] ans = new int[k];
        int j = 0;
        for (int i = 0; i &lt; nums.length; ++i) {
            while (j &gt; 0 &amp;&amp; nums[i] &gt; ans[j - 1] 
                &amp;&amp; nums.length - i &gt; k - j) --j;
            if (j &lt; k)
                ans[j++] = nums[i];
        }        
        return ans;
    }
    
    private int[] maxNumber(int[] nums1, int[] nums2) {
        int[] ans = new int[nums1.length + nums2.length];
        int s1 = 0;
        int s2 = 0;
        int index = 0;
        while (s1 != nums1.length || s2 != nums2.length)
            ans[index++] = max(nums1, s1, nums2, s2) == nums1 ? 
                           nums1[s1++] : nums2[s2++];
        return ans;
    }
    
    private int[] max(int[] nums1, int s1, int[] nums2, int s2) {
        for (int i = s1; i &lt; nums1.length; ++i) {
            int j = s2 + i - s1;
            if (j &gt;= nums2.length) return nums1;
            if (nums1[i] &lt; nums2[j]) return nums2;
            if (nums1[i] &gt; nums2[j]) return nums1;
        }
        return nums2;
    }
}</pre><p></div></div></p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-321-create-maximum-number/">花花酱 LeetCode 321. Create Maximum Number</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-321-create-maximum-number/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode  4. Median of Two Sorted Arrays</title>
		<link>https://zxi.mytechroad.com/blog/algorithms/binary-search/leetcode-4-median-of-two-sorted-arrays/</link>
					<comments>https://zxi.mytechroad.com/blog/algorithms/binary-search/leetcode-4-median-of-two-sorted-arrays/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Wed, 08 Nov 2017 16:33:09 +0000</pubDate>
				<category><![CDATA[Binary Search]]></category>
		<category><![CDATA[Hard]]></category>
		<category><![CDATA[binary search]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[median]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=747</guid>

					<description><![CDATA[<p>题目大意：求两个已经排序的数组的中位数（如果合并后）。 Problem: There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/algorithms/binary-search/leetcode-4-median-of-two-sorted-arrays/">花花酱 LeetCode  4. Median of Two Sorted Arrays</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/KB9IcSCDQ9k?feature=oembed" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></p>
<p>题目大意：求两个已经排序的数组的中位数（如果合并后）。</p>
<p><strong>Problem:</strong></p>
<p>There are two sorted arrays <b>nums1</b> and <b>nums2</b> of size m and n respectively.</p>
<p>Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).</p>
<p><b>Example 1:</b></p><pre class="crayon-plain-tag">nums1 = [1, 3]
nums2 = [2]

The median is 2.0</pre><p><b>Example 2:</b></p><pre class="crayon-plain-tag">nums1 = [1, 2]
nums2 = [3, 4]

The median is (2 + 3)/2 = 2.5</pre><p><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script><br />
<ins class="adsbygoogle" style="display: block; text-align: center;" data-ad-layout="in-article" data-ad-format="fluid" data-ad-client="ca-pub-2404451723245401" data-ad-slot="7983117522"></ins><br />
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></p>
<p><strong>Idea:</strong></p>
<p>Binary Search</p>
<p>Time complexity: O(log(min(n1,n2)))</p>
<p>Space complexity: O(1)</p>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/4-ep102.png"><img class="alignnone size-full wp-image-755" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/4-ep102.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/4-ep102.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/4-ep102-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/4-ep102-768x432.png 768w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/4-ep102-624x351.png 624w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/4-ep102-2.png"><img class="alignnone size-full wp-image-754" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/4-ep102-2.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/4-ep102-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/4-ep102-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/4-ep102-2-768x432.png 768w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/4-ep102-2-624x351.png 624w" sizes="(max-width: 960px) 100vw, 960px" /></a></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></p>
<h1><strong>Solution: Binary Search</strong></h1>
<p><div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 52 ms
class Solution {
public:
    double findMedianSortedArrays(vector&lt;int&gt;&amp; nums1, vector&lt;int&gt;&amp; nums2) {
        const int n1 = nums1.size();
        const int n2 = nums2.size();
        // Make sure n1 &lt;= n2
        if (n1 &gt; n2) return findMedianSortedArrays(nums2, nums1);
        
        const int k = (n1 + n2 + 1) / 2;

        int l = 0;
        int r = n1;
               
        while (l &lt; r) {
            const int m1 = l + (r - l) / 2;
            const int m2 = k - m1;
            if (nums1[m1] &lt; nums2[m2 - 1])
                l = m1 + 1;
            else
                r = m1;
        }
        
        const int m1 = l;
        const int m2 = k - l;
        
        const int c1 = max(m1 &lt;= 0 ? INT_MIN : nums1[m1 - 1], 
                           m2 &lt;= 0 ? INT_MIN : nums2[m2 - 1]);

        if ((n1 + n2) % 2 == 1)
            return c1;    
        
        const int c2 = min(m1 &gt;= n1 ? INT_MAX : nums1[m1], 
                           m2 &gt;= n2 ? INT_MAX : nums2[m2]);
                
        return (c1 + c2) * 0.5;
    }
};</pre><p></div><h2 class="tabtitle">Java</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 66 ms
class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int n1 = nums1.length;
        int n2 = nums2.length;
        if (n1 &gt; n2) 
            return findMedianSortedArrays(nums2, nums1);
        
        int k = (n1 + n2 + 1) / 2;
        int l = 0;
        int r = n1;
               
        while (l &lt; r) {
            int m1 = l + (r - l) / 2;
            int m2 = k - m1;
            if (nums1[m1] &lt; nums2[m2 - 1])
                l = m1 + 1;
            else
                r = m1;
        }
        
        int m1 = l;
        int m2 = k - l;
        
        int c1 = Math.max(m1 &lt;= 0 ? Integer.MIN_VALUE : nums1[m1 - 1], 
                          m2 &lt;= 0 ? Integer.MIN_VALUE : nums2[m2 - 1]);

        if ((n1 + n2) % 2 == 1)
            return c1;    
        
        int c2 = Math.min(m1 &gt;= n1 ? Integer.MAX_VALUE : nums1[m1], 
                          m2 &gt;= n2 ? Integer.MAX_VALUE : nums2[m2]);
                
        return (c1 + c2) * 0.5;
    }
}</pre><p></div></div></p>
<h1><strong>Related Problem:</strong></h1>
<ul>
<li><a href="http://zxi.mytechroad.com/blog/leetcode/leetcode-295-find-median-from-data-stream/">[解题报告] LeetCode 295. Find Median from Data Stream O(logn) + O(1)</a></li>
</ul>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/algorithms/binary-search/leetcode-4-median-of-two-sorted-arrays/">花花酱 LeetCode  4. Median of Two Sorted Arrays</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/algorithms/binary-search/leetcode-4-median-of-two-sorted-arrays/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 719. Find K-th Smallest Pair Distance</title>
		<link>https://zxi.mytechroad.com/blog/divide-and-conquer/leetcode-719-find-k-th-smallest-pair-distance/</link>
					<comments>https://zxi.mytechroad.com/blog/divide-and-conquer/leetcode-719-find-k-th-smallest-pair-distance/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 29 Oct 2017 20:14:10 +0000</pubDate>
				<category><![CDATA[Binary Search]]></category>
		<category><![CDATA[Divide and conquer]]></category>
		<category><![CDATA[Hard]]></category>
		<category><![CDATA[binary search]]></category>
		<category><![CDATA[bucket]]></category>
		<category><![CDATA[distance]]></category>
		<category><![CDATA[pair]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=710</guid>

					<description><![CDATA[<p>题目大意：给你一个数组，返回所有数对中，绝对值差第k小的值。 Problem: Given an integer array, return the k-th smallest distance among all the pairs. The distance of a pair (A, B) is defined as the absolute&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/divide-and-conquer/leetcode-719-find-k-th-smallest-pair-distance/">花花酱 LeetCode 719. Find K-th Smallest Pair Distance</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/WHfljqX61Y8?feature=oembed" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></p>
<p>题目大意：给你一个数组，返回所有数对中，绝对值差第k小的值。</p>
<p><strong>Problem:</strong></p>
<p>Given an integer array, return the k-th smallest <b>distance</b> among all the pairs. The distance of a pair (A, B) is defined as the absolute difference between A and B.</p>
<p><b>Example 1:</b></p><pre class="crayon-plain-tag">Input:
nums = [1,3,1]
k = 1
Output: 0 
Explanation:
Here are all the pairs:
(1,3) -&gt; 2
(1,1) -&gt; 0
(3,1) -&gt; 2
Then the 1st smallest distance pair is (1,1), and its distance is 0.</pre><p><b>Note:</b></p>
<ol>
<li><code>2 &lt;= len(nums) &lt;= 10000</code>.</li>
<li><code>0 &lt;= nums[i] &lt; 1000000</code>.</li>
<li><code>1 &lt;= k &lt;= len(nums) * (len(nums) - 1) / 2</code>.</li>
</ol>
<p><strong>Idea</strong></p>
<p>Bucket sort</p>
<p>Binary search / dp</p>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/719-ep99-1.png"><img class="alignnone size-full wp-image-720" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/719-ep99-1.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/719-ep99-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/719-ep99-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/719-ep99-1-768x432.png 768w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/719-ep99-1-624x351.png 624w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/719-ep99-2.png"><img class="alignnone size-full wp-image-719" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/719-ep99-2.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/719-ep99-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/719-ep99-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/719-ep99-2-768x432.png 768w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/719-ep99-2-624x351.png 624w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<p><strong>Solution</strong></p>
<p>C++ / binary search</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 9 ms
class Solution {
public:
    int smallestDistancePair(vector&lt;int&gt;&amp; nums, int k) {
        std::sort(nums.begin(), nums.end());
        int n = nums.size();
        int l = 0;
        int r = nums.back() - nums.front();
        while (l &lt;= r) {
            int cnt = 0;
            int j = 0;
            int m = l + (r - l) / 2;
            for (int i = 0; i &lt; n; ++i) {
                while (j &lt; n &amp;&amp; nums[j] - nums[i] &lt;= m) ++j;
                cnt += j - i - 1;
            }
            cnt &gt;= k ? r = m - 1 : l = m + 1;
        }        
        return l;
    }
};</pre><p>&nbsp;</p>
<p>C++ / bucket sort w/ vector O(n^2)</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 549 ms
class Solution {
public:
    int smallestDistancePair(vector&lt;int&gt;&amp; nums, int k) {
        std::sort(nums.begin(), nums.end());
        const int N = nums.back();
        vector&lt;int&gt; count(N + 1, 0);        
        const int n = nums.size();
        for (int i = 0; i &lt; n; ++i)
            for (int j = i + 1; j &lt; n; ++j)
               ++count[nums[j] - nums[i]];
        for (int i = 0; i &lt;= N; ++i) {
            k -= count[i];
            if (k &lt;= 0) return i;
        }
        return 0;
    }
};</pre><p><strong>Related Problems:</strong></p>
<ul>
<li><a href="http://zxi.mytechroad.com/blog/two-pointers/leetcode-786-k-th-smallest-prime-fraction/">花花酱 LeetCode 786. K-th Smallest Prime Fraction</a></li>
<li><a href="http://zxi.mytechroad.com/blog/algorithms/binary-search/leetcode-378-kth-smallest-element-in-a-sorted-matrix/">花花酱 LeetCode 378. Kth Smallest Element in a Sorted Matrix</a></li>
</ul>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/divide-and-conquer/leetcode-719-find-k-th-smallest-pair-distance/">花花酱 LeetCode 719. Find K-th Smallest Pair Distance</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/divide-and-conquer/leetcode-719-find-k-th-smallest-pair-distance/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 699. Falling Squares</title>
		<link>https://zxi.mytechroad.com/blog/geometry/leetcode-699-falling-squares/</link>
					<comments>https://zxi.mytechroad.com/blog/geometry/leetcode-699-falling-squares/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Wed, 25 Oct 2017 03:09:00 +0000</pubDate>
				<category><![CDATA[Geometry]]></category>
		<category><![CDATA[Hard]]></category>
		<category><![CDATA[height]]></category>
		<category><![CDATA[max]]></category>
		<category><![CDATA[range]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=693</guid>

					<description><![CDATA[<p>题目大意：方块落下后会堆叠在重叠的方块之上，问每一块方块落下之后最高的方块的高度是多少？ Problem: On an infinite number line (x-axis), we drop given squares in the order they are given. The i-th square dropped (positions[i] = (left, side_length))&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/geometry/leetcode-699-falling-squares/">花花酱 LeetCode 699. Falling Squares</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/UeuV-6Ygxs4?feature=oembed" frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen></iframe></p>
<p>题目大意：方块落下后会堆叠在重叠的方块之上，问每一块方块落下之后最高的方块的高度是多少？</p>
<p><strong>Problem:</strong></p>
<p>On an infinite number line (x-axis), we drop given squares in the order they are given.</p>
<p>The <code>i</code>-th square dropped (<code>positions[i] = (left, side_length)</code>) is a square with the left-most point being <code>positions[i][0]</code> and sidelength <code>positions[i][1]</code>.</p>
<p>The square is dropped with the bottom edge parallel to the number line, and from a higher height than all currently landed squares. We wait for each square to stick before dropping the next.</p>
<p>The squares are infinitely sticky on their bottom edge, and will remain fixed to any positive length surface they touch (either the number line or another square). Squares dropped adjacent to each other will not stick together prematurely.</p>
<p>&nbsp;</p>
<p>Return a list <code>ans</code> of heights. Each height <code>ans[i]</code> represents the current highest height of any square we have dropped, after dropping squares represented by <code>positions[0], positions[1], ..., positions[i]</code>.</p>
<p><b>Example 1:</b></p><pre class="crayon-plain-tag">Input: [[1, 2], [2, 3], [6, 1]]
Output: [2, 5, 5]
Explanation:

After the first drop of 
positions[0] = [1, 2]:
_aa
_aa
-------
The maximum height of any square is 2.


After the second drop of 
positions[1] = [2, 3]:
__aaa
__aaa
__aaa
_aa__
_aa__
--------------
The maximum height of any square is 5.  
The larger square stays on top of the smaller square despite where its center
of gravity is, because squares are infinitely sticky on their bottom edge.


After the third drop of 
positions[1] = [6, 1]:
__aaa
__aaa
__aaa
_aa
_aa___a
--------------
The maximum height of any square is still 5.

Thus, we return an answer of 
[2, 5, 5]</pre><p><b>Example 2:</b></p><pre class="crayon-plain-tag">Input: [[100, 100], [200, 100]]
Output: [100, 100]
Explanation: Adjacent squares don't get stuck prematurely - only their bottom edge can stick to surfaces.</pre><p><b>Note:</b></p>
<p>&nbsp;</p>
<ul>
<li><code>1 &lt;= positions.length &lt;= 1000</code>.</li>
<li><code>1 &lt;= positions[i][0] &lt;= 10^8</code>.</li>
<li><code>1 &lt;= positions[i][1] &lt;= 10^6</code>.</li>
</ul>
<p><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script><br />
<ins class="adsbygoogle" style="display: block; text-align: center;" data-ad-layout="in-article" data-ad-format="fluid" data-ad-client="ca-pub-2404451723245401" data-ad-slot="7983117522"></ins><br />
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></p>
<p><strong>Idea:</strong></p>
<p>Range query with map</p>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/699-ep97-1.png"><img class="alignnone size-full wp-image-701" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/699-ep97-1.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/699-ep97-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/699-ep97-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/699-ep97-1-768x432.png 768w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/699-ep97-1-624x351.png 624w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/699-ep97-2.png"><img class="alignnone size-full wp-image-700" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/699-ep97-2.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/699-ep97-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/699-ep97-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/699-ep97-2-768x432.png 768w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/699-ep97-2-624x351.png 624w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<p>&nbsp;</p>
<p><strong>Solution:</strong></p>
<p>C++ map</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 29 ms
class Solution {
public:
    vector&lt;int&gt; fallingSquares(vector&lt;pair&lt;int, int&gt;&gt;&amp; positions) {
        vector&lt;int&gt; ans;
        map&lt;pair&lt;int, int&gt;, int&gt; b; // {{start, end}, height}        
        int maxHeight = INT_MIN;
        for (const auto&amp; kv: positions) {
            int start = kv.first;
            int size = kv.second;
            int end = start + size;
            // first range intersect with new_interval
            auto it = b.upper_bound({start, end});
            if (it != b.begin()) {
                auto it2 = it;
                if ((--it2)-&gt;first.second &gt; start) it = it2;
            }
            
            int baseHeight = 0;
            vector&lt;tuple&lt;int, int, int&gt;&gt; ranges;
            while (it != b.end() &amp;&amp; it-&gt;first.first &lt; end) {
                const int s = it-&gt;first.first;
                const int e = it-&gt;first.second;
                const int h = it-&gt;second;
                if (s &lt; start) ranges.emplace_back(s, start, h);
                if (e &gt; end) ranges.emplace_back(end, e, h);
                // max height of intesected ranges
                baseHeight = max(baseHeight, h);
                it = b.erase(it);
            }
            
            int newHeight = size + baseHeight;
            
            b[{start, end}] = newHeight;
            
            for (const auto&amp; range: ranges)
                b[{get&lt;0&gt;(range), get&lt;1&gt;(range)}] = get&lt;2&gt;(range);
            
            maxHeight = max(maxHeight, newHeight);            
            ans.push_back(maxHeight);
        }
        return ans;
    }
};</pre><p>&nbsp;</p>
<p>C++ vector without merge</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 46 ms
class Solution {
public:
    vector&lt;int&gt; fallingSquares(vector&lt;pair&lt;int, int&gt;&gt;&amp; positions) {
        vector&lt;int&gt; ans;
        vector&lt;Interval&gt; intervals;
        int maxHeight = INT_MIN;
        for (const auto&amp; kv: positions) {
            int start = kv.first;
            int end = start + kv.second;            
            int baseHeight = 0;
            for (const Interval&amp; interval : intervals) {
                if (interval.start &gt;= end || interval.end &lt;= start)             
                    continue;
                baseHeight = max(baseHeight, interval.height);
            }
            int height = kv.second + baseHeight;
            intervals.push_back(Interval(start, end, height));
            maxHeight = max(maxHeight, height);
            ans.push_back(maxHeight);
        }
        return ans;
    }
private:
    struct Interval {
        int start;
        int end;
        int height;
        Interval(int start, int end, int height) 
            : start(start), end(end), height(height) {}
    };
};</pre><p>C++ / vector with merge (slower)</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 86 ms
class Solution {
public:
    vector&lt;int&gt; fallingSquares(vector&lt;pair&lt;int, int&gt;&gt;&amp; positions) {
        vector&lt;int&gt; ans;
        vector&lt;Interval&gt; intervals;
        int maxHeight = INT_MIN;
        for (const auto&amp; kv: positions) {
            vector&lt;Interval&gt; tmp;
            int start = kv.first;
            int end = start + kv.second;            
            int baseHeight = 0;
            for (const Interval&amp; interval : intervals) {
                if (interval.start &gt;= end || interval.end &lt;= start) {
                    tmp.push_back(interval);                
                    continue;
                }
                baseHeight = max(baseHeight, interval.height);
                if (interval.start &lt; start || interval.end &gt; end)
                    tmp.push_back(interval);
            }
            int height = kv.second + baseHeight;
            tmp.push_back(Interval(start, end, height));
            intervals.swap(tmp);
            maxHeight = max(maxHeight, height);
            ans.push_back(maxHeight);
        }
        return ans;
    }
private:
    struct Interval {
        int start;
        int end;
        int height;
        Interval(int start, int end, int height) 
            : start(start), end(end), height(height) {}
    };
};</pre><p>&nbsp;</p>
<p><strong>Related Problems:</strong></p>
<ul>
<li><a href="http://zxi.mytechroad.com/blog/data-structure/leetcode-715-range-module/">[解题报告] LeetCode 715. Range Module</a></li>
<li><a href="http://zxi.mytechroad.com/blog/tree/leetcode-218-the-skyline-problem/">[解题报告] LeetCode 218. The Skyline Problem</a></li>
<li>[解题报告] LeetCode 57. Insert Interval</li>
</ul>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/geometry/leetcode-699-falling-squares/">花花酱 LeetCode 699. Falling Squares</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/geometry/leetcode-699-falling-squares/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 715. Range Module</title>
		<link>https://zxi.mytechroad.com/blog/data-structure/leetcode-715-range-module/</link>
					<comments>https://zxi.mytechroad.com/blog/data-structure/leetcode-715-range-module/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 22 Oct 2017 23:29:45 +0000</pubDate>
				<category><![CDATA[Data Structure]]></category>
		<category><![CDATA[Geometry]]></category>
		<category><![CDATA[Hard]]></category>
		<category><![CDATA[query]]></category>
		<category><![CDATA[range]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=679</guid>

					<description><![CDATA[<p>Problem: A Range Module is a module that tracks ranges of numbers. Your task is to design and implement the following interfaces in an efficient&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/data-structure/leetcode-715-range-module/">花花酱 LeetCode 715. Range Module</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/pcpB9ux3RrQ?feature=oembed" frameborder="0" gesture="media" allowfullscreen></iframe></p>
<p><strong>Problem:</strong></p>
<p>A Range Module is a module that tracks ranges of numbers. Your task is to design and implement the following interfaces in an efficient manner.</p>
<p>&nbsp;</p>
<ul>
<li><code>addRange(int left, int right)</code> Adds the half-open interval <code>[left, right)</code>, tracking every real number in that interval. Adding an interval that partially overlaps with currently tracked numbers should add any numbers in the interval <code>[left, right)</code> that are not already tracked.</li>
<li><code>queryRange(int left, int right)</code> Returns true if and only if every real number in the interval <code>[left, right)</code> is currently being tracked.</li>
<li><code>removeRange(int left, int right)</code> Stops tracking every real number currently being tracked in the interval <code>[left, right)</code>.</li>
</ul>
<p><b>Example 1:</b></p><pre class="crayon-plain-tag">addRange(10, 20): null
removeRange(14, 16): null
queryRange(10, 14): true (Every number in [10, 14) is being tracked)
queryRange(13, 15): false (Numbers like 14, 14.03, 14.17 in [13, 15) are not being tracked)
queryRange(16, 17): true (The number 16 in [16, 17) is still being tracked, despite the remove operation)</pre><p><b>Note:</b></p>
<ul>
<li>A half open interval <code>[left, right)</code> denotes all real numbers <code>left &lt;= x &lt; right</code>.</li>
<li><code>0 &lt; left &lt; right &lt; 10^9</code> in all calls to <code>addRange, queryRange, removeRange</code>.</li>
<li>The total number of calls to <code>addRange</code> in a single test case is at most <code>1000</code>.</li>
<li>The total number of calls to <code>queryRange</code> in a single test case is at most <code>5000</code>.</li>
<li>The total number of calls to <code>removeRange</code> in a single test case is at most <code>1000</code>.</li>
</ul>
<p><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script><br />
<ins class="adsbygoogle" style="display: block; text-align: center;" data-ad-layout="in-article" data-ad-format="fluid" data-ad-client="ca-pub-2404451723245401" data-ad-slot="7983117522"></ins><br />
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></p>
<p><strong>Idea:</strong></p>
<p>map / ordered ranges</p>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/715-ep96-1.png"><img class="alignnone size-full wp-image-689" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/715-ep96-1.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/715-ep96-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/715-ep96-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/715-ep96-1-768x432.png 768w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/715-ep96-1-624x351.png 624w" sizes="(max-width: 960px) 100vw, 960px" /></a>  <a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/715-ep96-2.png"><img class="alignnone size-full wp-image-688" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/715-ep96-2.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/715-ep96-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/715-ep96-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/715-ep96-2-768x432.png 768w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/715-ep96-2-624x351.png 624w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/715-ep96-3.png"><img class="alignnone size-full wp-image-687" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/715-ep96-3.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/715-ep96-3.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/715-ep96-3-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/715-ep96-3-768x432.png 768w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/715-ep96-3-624x351.png 624w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/715-ep96-4.png"><img class="alignnone size-full wp-image-686" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/715-ep96-4.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/715-ep96-4.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/715-ep96-4-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/715-ep96-4-768x432.png 768w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/10/715-ep96-4-624x351.png 624w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<p>&nbsp;</p>
<p><strong>Solution:</strong></p>
<p>C++ / vector</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 276 ms
class RangeModule {
public:
    RangeModule() {}
    
    void addRange(int left, int right) {
        vector&lt;pair&lt;int, int&gt;&gt; new_ranges;
        bool inserted = false;
        for (const auto&amp; kv : ranges_) {            
            if (kv.first &gt; right &amp;&amp; !inserted) {
                new_ranges.emplace_back(left, right);
                inserted = true;
            }
            if (kv.second &lt; left || kv.first &gt; right) { 
                new_ranges.push_back(kv);
            } else {
                left = min(left, kv.first);
                right = max(right, kv.second);
            }
        }       
        if (!inserted) new_ranges.emplace_back(left, right);       
        ranges_.swap(new_ranges);
    }
    
    bool queryRange(int left, int right) {
        const int n = ranges_.size();
        int l = 0;
        int r = n - 1;
        // Binary search
        while (l &lt;= r) {
            int m = l + (r - l) / 2;
            if (ranges_[m].second &lt; left)
                l = m + 1;
            else if (ranges_[m].first &gt; right)
                r = m - 1;
            else
                return ranges_[m].first &lt;= left &amp;&amp; ranges_[m].second &gt;= right;
        }
        return false;
    }
    
    void removeRange(int left, int right) {
        vector&lt;pair&lt;int, int&gt;&gt; new_ranges;        
        for (const auto&amp; kv : ranges_) {
            if (kv.second &lt;= left || kv.first &gt;= right) {
                new_ranges.push_back(kv);
            } else {
                if (kv.first &lt; left)
                    new_ranges.emplace_back(kv.first, left);
                if (kv.second &gt; right)
                    new_ranges.emplace_back(right, kv.second);
            }        
        }
        ranges_.swap(new_ranges);
    }
    vector&lt;pair&lt;int, int&gt;&gt; ranges_;
};</pre><p>C++ / map</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 199 ms
class RangeModule {
public:
    RangeModule() {}
    
    void addRange(int left, int right) {
        IT l, r;
        getOverlapRanges(left, right, l, r);
        // At least one range overlapping with [left, right)
        if (l != r) {
            // Merge intervals into [left, right)
            auto last = r; --last;
            left = min(left, l-&gt;first);            
            right = max(right, last-&gt;second);
            // Remove all overlapped ranges
            ranges_.erase(l, r);
        }
        // Add a new/merged range
        ranges_[left] = right;
    }
    
    bool queryRange(int left, int right) {
        IT l, r;
        getOverlapRanges(left, right, l, r);
        // No overlapping range
        if (l == r) return false;
        return l-&gt;first &lt;= left &amp;&amp; l-&gt;second &gt;= right;
    }
    
    void removeRange(int left, int right) {
        IT l, r;
        getOverlapRanges(left, right, l, r);
        // No overlapping range
        if (l == r) return;
        auto last = r; --last;
        int start = min(left, l-&gt;first);        
        int end = max(right, last-&gt;second);
        // Delete overlapping ranges        
        ranges_.erase(l, r);
        if (start &lt; left) ranges_[start] = left;
        if (end &gt; right) ranges_[right] = end;
    }
private:
    typedef map&lt;int, int&gt;::iterator IT;
    map&lt;int, int&gt; ranges_;
    void getOverlapRanges(int left, int right, IT&amp; l, IT&amp; r) {
        l = ranges_.upper_bound(left);
        r = ranges_.upper_bound(right);
        if (l != ranges_.begin())
            if ((--l)-&gt;second &lt; left) l++;
    }
};</pre><p><strong>Related Problems:</strong></p>
<ul>
<li><a href="http://zxi.mytechroad.com/blog/geometry/leetcode-57-insert-interval/">[解题报告] LeetCode 57. Insert Interval</a></li>
<li><a href="http://zxi.mytechroad.com/blog/geometry/leetcode-56-merge-intervals/">[解题报告] LeetCode 56. Merge Intervals</a></li>
</ul>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/data-structure/leetcode-715-range-module/">花花酱 LeetCode 715. Range Module</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/data-structure/leetcode-715-range-module/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
