<?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>range Archives - Huahua&#039;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/tag/range/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog/tag/range/</link>
	<description></description>
	<lastBuildDate>Wed, 15 Dec 2021 06:01:13 +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>range Archives - Huahua&#039;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog/tag/range/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>花花酱 LeetCode 2106. Maximum Fruits Harvested After at Most K Steps</title>
		<link>https://zxi.mytechroad.com/blog/algorithms/array/leetcode-2106-maximum-fruits-harvested-after-at-most-k-steps/</link>
					<comments>https://zxi.mytechroad.com/blog/algorithms/array/leetcode-2106-maximum-fruits-harvested-after-at-most-k-steps/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 13 Dec 2021 02:49:45 +0000</pubDate>
				<category><![CDATA[Array]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[query]]></category>
		<category><![CDATA[range]]></category>
		<category><![CDATA[range query]]></category>
		<category><![CDATA[sliding window]]></category>
		<category><![CDATA[sum]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9171</guid>

					<description><![CDATA[<p>Problem Solution 1: Range sum query Assuming we can collect fruits in range [l, r], we need a fast query to compute the sum of&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/algorithms/array/leetcode-2106-maximum-fruits-harvested-after-at-most-k-steps/">花花酱 LeetCode 2106. Maximum Fruits Harvested After at Most K Steps</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h2><strong><a href="http://2106. Maximum Fruits Harvested After at Most K Steps">Problem</a></strong></h2>



<p></p>



<h2><strong>Solution 1: Range sum query</strong></h2>



<p>Assuming we can collect fruits in range [l, r], we need a fast query to compute the sum of those fruits.</p>



<p>Given startPos and k, we have four options:<br>1. move i steps to the left<br>2. move i steps to the left and k &#8211; i steps to the right.<br>3. move i steps to the right<br>4. move i steps to the right and k &#8211; i steps to the left.</p>



<p>We enumerate i steps and calculate maximum range [l, r] covered by each option, and collect all the fruit in that range.</p>



<p>Time complexity: O(m + k)<br>Space complexity: O(m)<br>where m = max(max(pos), startPos)</p>



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

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  int maxTotalFruits(vector&lt;vector&lt;int&gt;&gt;&amp; fruits, int startPos, int k) {    
    const int m = max(startPos, (*max_element(begin(fruits), end(fruits)))[0]);
    vector&lt;int&gt; sums(m + 2);   
    for (int i = 0, j = 0; i &lt;= m; ++i) {
      sums[i + 1] += sums[i];
      while (j &lt; fruits.size() &amp;&amp; fruits[j][0] == i)        
        sums[i + 1] += fruits[j++][1];      
    }    
    int ans = 0;
    for (int s = 0; s &lt;= k; ++s) {
      if (startPos - s &gt;= 0) {
        int l = startPos - s;
        int r = min(max(startPos, l + (k - s)), m);        
        ans = max(ans, sums[r + 1] - sums[l]);
      }
      if (startPos + s &lt;= m) {
        int r = startPos + s;
        int l = max(0, min(startPos, r - (k - s)));
        ans = max(ans, sums[r + 1] - sums[l]);
      }
    }             
    return ans;
  }
};</pre>
</div></div>



<h2><strong>Solution 2: Sliding Window</strong></h2>



<p>Maintain a window [l, r] such that the steps to cover [l, r] from startPos is less or equal to k.</p>



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



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

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  int maxTotalFruits(vector&lt;vector&lt;int&gt;&gt;&amp; fruits, int startPos, int k) {    
    auto steps = [&amp;](int l, int r) {
      if (r &lt;= startPos)
        return startPos - l;
      else if (l &gt;= startPos)
        return r - startPos;
      else
        return min(startPos + r - 2 * l, 2 * r - startPos - l);
    };
    int ans = 0;
    for (int r = 0, l = 0, cur = 0; r &lt; fruits.size(); ++r) {
      cur += fruits[r][1];
      while (l &lt;= r &amp;&amp; steps(fruits[l][0], fruits[r][0]) &gt; k)
        cur -= fruits[l++][1];      
      ans = max(ans, cur);
    }
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/algorithms/array/leetcode-2106-maximum-fruits-harvested-after-at-most-k-steps/">花花酱 LeetCode 2106. Maximum Fruits Harvested After at Most K Steps</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-2106-maximum-fruits-harvested-after-at-most-k-steps/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1893. Check if All the Integers in a Range Are Covered</title>
		<link>https://zxi.mytechroad.com/blog/hashtable/leetcode-1893-check-if-all-the-integers-in-a-range-are-covered/</link>
					<comments>https://zxi.mytechroad.com/blog/hashtable/leetcode-1893-check-if-all-the-integers-in-a-range-are-covered/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Tue, 10 Aug 2021 02:26:48 +0000</pubDate>
				<category><![CDATA[Hashtable]]></category>
		<category><![CDATA[easy]]></category>
		<category><![CDATA[hashtable]]></category>
		<category><![CDATA[range]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8549</guid>

					<description><![CDATA[<p>You are given a 2D integer array&#160;ranges&#160;and two integers&#160;left&#160;and&#160;right. Each&#160;ranges[i] = [starti, endi]&#160;represents an&#160;inclusive&#160;interval between&#160;starti&#160;and&#160;endi. Return&#160;true&#160;if each integer in the inclusive range&#160;[left, right]&#160;is covered by&#160;at&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/hashtable/leetcode-1893-check-if-all-the-integers-in-a-range-are-covered/">花花酱 LeetCode 1893. Check if All the Integers in a Range Are Covered</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>You are given a 2D integer array&nbsp;<code>ranges</code>&nbsp;and two integers&nbsp;<code>left</code>&nbsp;and&nbsp;<code>right</code>. Each&nbsp;<code>ranges[i] = [start<sub>i</sub>, end<sub>i</sub>]</code>&nbsp;represents an&nbsp;<strong>inclusive</strong>&nbsp;interval between&nbsp;<code>start<sub>i</sub></code>&nbsp;and&nbsp;<code>end<sub>i</sub></code>.</p>



<p>Return&nbsp;<code>true</code>&nbsp;<em>if each integer in the inclusive range</em>&nbsp;<code>[left, right]</code>&nbsp;<em>is covered by&nbsp;<strong>at least one</strong>&nbsp;interval in</em>&nbsp;<code>ranges</code>. Return&nbsp;<code>false</code>&nbsp;<em>otherwise</em>.</p>



<p>An integer&nbsp;<code>x</code>&nbsp;is covered by an interval&nbsp;<code>ranges[i] = [start<sub>i</sub>, end<sub>i</sub>]</code>&nbsp;if&nbsp;<code>start<sub>i</sub>&nbsp;&lt;= x &lt;= end<sub>i</sub></code>.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> ranges = [[1,2],[3,4],[5,6]], left = 2, right = 5
<strong>Output:</strong> true
<strong>Explanation:</strong> Every integer between 2 and 5 is covered:
- 2 is covered by the first range.
- 3 and 4 are covered by the second range.
- 5 is covered by the third range.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> ranges = [[1,10],[10,20]], left = 21, right = 21
<strong>Output:</strong> false
<strong>Explanation:</strong> 21 is not covered by any range.
</pre>



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



<ul><li><code>1 &lt;= ranges.length &lt;= 50</code></li><li><code>1 &lt;= start<sub>i</sub>&nbsp;&lt;= end<sub>i</sub>&nbsp;&lt;= 50</code></li><li><code>1 &lt;= left &lt;= right &lt;= 50</code></li></ul>



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



<p>Time complexity: O(n * (right &#8211; left))<br>Space complexity: O(right &#8211; left)</p>



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

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:  
  bool isCovered(vector&lt;vector&lt;int&gt;&gt;&amp; ranges, int left, int right) {
    unordered_set&lt;int&gt; s;
    for (const auto&amp; range : ranges)
      for (int i = max(left, range[0]); i &lt;= min(right, range[1]); ++i)
        s.insert(i);    
    return s.size() == right - left + 1;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/hashtable/leetcode-1893-check-if-all-the-integers-in-a-range-are-covered/">花花酱 LeetCode 1893. Check if All the Integers in a Range Are Covered</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/hashtable/leetcode-1893-check-if-all-the-integers-in-a-range-are-covered/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1751. Maximum Number of Events That Can Be Attended II</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1751-maximum-number-of-events-that-can-be-attended-ii/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1751-maximum-number-of-events-that-can-be-attended-ii/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 06 Feb 2021 16:37:38 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[binary search]]></category>
		<category><![CDATA[date]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[range]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8071</guid>

					<description><![CDATA[<p>You are given an array of&#160;events&#160;where&#160;events[i] = [startDayi, endDayi, valuei]. The&#160;ith&#160;event starts at&#160;startDayiand ends at&#160;endDayi, and if you attend this event, you will receive a&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1751-maximum-number-of-events-that-can-be-attended-ii/">花花酱 LeetCode 1751. Maximum Number of Events That Can Be Attended 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>You are given an array of&nbsp;<code>events</code>&nbsp;where&nbsp;<code>events[i] = [startDay<sub>i</sub>, endDay<sub>i</sub>, value<sub>i</sub>]</code>. The&nbsp;<code>i<sup>th</sup></code>&nbsp;event starts at&nbsp;<code>startDay<sub>i</sub></code>and ends at&nbsp;<code>endDay<sub>i</sub></code>, and if you attend this event, you will receive a value of&nbsp;<code>value<sub>i</sub></code>. You are also given an integer&nbsp;<code>k</code>&nbsp;which represents the maximum number of events you can attend.</p>



<p>You can only attend one event at a time. If you choose to attend an event, you must attend the&nbsp;<strong>entire</strong>&nbsp;event. Note that the end day is&nbsp;<strong>inclusive</strong>: that is, you cannot attend two events where one of them starts and the other ends on the same day.</p>



<p>Return&nbsp;<em>the&nbsp;<strong>maximum sum</strong>&nbsp;of values that you can receive by attending events.</em></p>



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



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> events = [[1,2,4],[3,4,3],[2,3,1]], k = 2
<strong>Output:</strong> 7
<strong>Explanation: </strong>Choose the green events, 0 and 1 (0-indexed) for a total value of 4 + 3 = 7.</pre>



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



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> events = [[1,2,4],[3,4,3],[2,3,10]], k = 2
<strong>Output:</strong> 10
<strong>Explanation:</strong> Choose event 2 for a total value of 10.
Notice that you cannot attend any other event as they overlap, and that you do <strong>not</strong> have to attend k events.</pre>



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



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> events = [[1,1,1],[2,2,2],[3,3,3],[4,4,4]], k = 3
<strong>Output:</strong> 9
<strong>Explanation:</strong> Although the events do not overlap, you can only attend 3 events. Pick the highest valued three.</pre>



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



<ul><li><code>1 &lt;= k &lt;= events.length</code></li><li><code>1 &lt;= k * events.length &lt;= 10<sup>6</sup></code></li><li><code>1 &lt;= startDay<sub>i</sub>&nbsp;&lt;= endDay<sub>i</sub>&nbsp;&lt;= 10<sup>9</sup></code></li><li><code>1 &lt;= value<sub>i</sub>&nbsp;&lt;= 10<sup>6</sup></code></li></ul>



<h2><strong>Solution: DP + Binary Search</strong></h2>



<p>Sort events by ending time.<br>dp[i][j] := max value we can get by attending <strong><span class="has-inline-color has-vivid-red-color">at most</span></strong> j events among events[0~i].<br>dp[i][j] = max(dp[i &#8211; 1][j],  dp[p][j &#8211; 1] + value[i])<br>p is the first event that does not overlap with the current one.</p>



<p>Time complexity: O(nlogn + nk)<br>Space complexity: O(nk)</p>



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

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  int maxValue(vector&lt;vector&lt;int&gt;&gt;&amp; events, int k) {
    const int n = events.size(); 
    vector&lt;vector&lt;int&gt;&gt; dp(n + 1, vector&lt;int&gt;(k + 1));    
    vector&lt;int&gt; e(n);
    auto comp = [](const vector&lt;int&gt;&amp; a, const vector&lt;int&gt;&amp; b) {
      return a[1] &lt; b[1];
    };
    
    sort(begin(events), end(events), comp);
    
    for (int i = 1; i &lt;= n; ++i) {
      const int p = lower_bound(begin(events), 
                                begin(events) + i, 
                                vector&lt;int&gt;{0, events[i - 1][0], 0},
                                comp) - begin(events);
      for (int j = 1; j &lt;= k; ++j)
        dp[i][j] = max(dp[i - 1][j], 
                       dp[p][j - 1] + events[i - 1][2]);
    }    
    return dp[n][k];
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1751-maximum-number-of-events-that-can-be-attended-ii/">花花酱 LeetCode 1751. Maximum Number of Events That Can Be Attended 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-1751-maximum-number-of-events-that-can-be-attended-ii/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1563. Stone Game V</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1563-stone-game-v/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1563-stone-game-v/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 23 Aug 2020 18:55:17 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[prefix sum]]></category>
		<category><![CDATA[range]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7304</guid>

					<description><![CDATA[<p>There are several stones&#160;arranged in a row, and each stone has an associated&#160;value which is an integer given in the array&#160;stoneValue. In each round of&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1563-stone-game-v/">花花酱 LeetCode 1563. Stone Game V</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="花花酱 LeetCode 1563. Stone Game V - 刷题找工作 EP352" width="500" height="281" src="https://www.youtube.com/embed/RQSYQGhBDsg?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div></figure>



<p>There are several stones&nbsp;<strong>arranged in a row</strong>, and each stone has an associated&nbsp;value which is an integer given in the array&nbsp;<code>stoneValue</code>.</p>



<p>In each round of the game, Alice divides the row into&nbsp;<strong>two non-empty rows</strong>&nbsp;(i.e. left row and right row), then Bob calculates the value of each row which is the sum of the values of all the stones in this row. Bob throws away the row which has the maximum value, and&nbsp;Alice&#8217;s score increases by the value of the remaining row. If the value of the two rows are equal, Bob lets Alice decide which row will be thrown away. The next round starts with the remaining row.</p>



<p>The game ends when there is only&nbsp;<strong>one stone remaining</strong>. Alice&#8217;s is initially&nbsp;<strong>zero</strong>.</p>



<p>Return&nbsp;<em>the maximum score that Alice can obtain</em>.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> stoneValue = [6,2,3,4,5,5]
<strong>Output:</strong> 18
<strong>Explanation:</strong> In the first round, Alice divides the row to [6,2,3], [4,5,5]. The left row has the value 11 and the right row has value 14. Bob throws away the right row and Alice's score is now 11.
In the second round Alice divides the row to [6], [2,3]. This time Bob throws away the left row and Alice's score becomes 16 (11 + 5).
The last round Alice has only one choice to divide the row which is [2], [3]. Bob throws away the right row and Alice's score is now 18 (16 + 2). The game ends because only one stone is remaining in the row.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> stoneValue = [7,7,7,7,7,7,7]
<strong>Output:</strong> 28
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> stoneValue = [4]
<strong>Output:</strong> 0
</pre>



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



<ul><li><code>1 &lt;= stoneValue.length &lt;= 500</code></li><li><code>1 &lt;=&nbsp;stoneValue[i] &lt;= 10^6</code></li></ul>



<h2><strong>Solution: Range DP + Prefix Sum</strong></h2>



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



<figure class="wp-block-image size-large"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/08/1563-ep352-2.png" alt="" class="wp-image-7310" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/08/1563-ep352-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/08/1563-ep352-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/08/1563-ep352-2-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></figure>



<p>dp[l][r] := max store Alice can get from range [l, r]<br>sum_l = sum(l, k), sum_r = sum(k + 1, r)<br>dp[l][r] = max{<br>  dp[l][k] + sum_l if sum_l &lt; sum_r<br>  dp[k+1][r] + sum_r if sum_r &lt; sum_l <br>  max(dp[l][k], dp[k+1][r])) + sum_l if sum_l == sum_r)<br>} for k in [l, r)</p>



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



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

<pre class="crayon-plain-tag">class Solution {
public:
  int stoneGameV(vector&lt;int&gt;&amp; stoneValue) {
    const int n = stoneValue.size();
    vector&lt;int&gt; sums(n + 1);
    for (int i = 0; i &lt; n; ++i)
      sums[i + 1] = sums[i] + stoneValue[i];
    vector&lt;vector&lt;int&gt;&gt; cache(n, vector&lt;int&gt;(n, -1));
    // max value alice can get from range [l, r]
    function&lt;int(int, int)&gt; dp = [&amp;](int l, int r) {
      if (l == r) return 0;
      int&amp; ans = cache[l][r];
      if (ans != -1) return ans;
      for (int k = l; k &lt; r; ++k) {
        // left: [l, k], right: [k + 1, r]
        int sum_l = sums[k + 1] - sums[l];
        int sum_r = sums[r + 1] - sums[k + 1];
        if (sum_l &gt; sum_r)
          ans = max(ans, sum_r + dp(k + 1, r));
        else if (sum_l &lt; sum_r)
          ans = max(ans, sum_l + dp(l, k));
        else
          ans = max(ans, sum_l + max(dp(l, k), dp(k + 1, r)));
      }      
      return ans;
    };
    
    return dp(0, n - 1);
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1563-stone-game-v/">花花酱 LeetCode 1563. Stone Game V</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-1563-stone-game-v/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 938. Range Sum of BST</title>
		<link>https://zxi.mytechroad.com/blog/tree/leetcode-938-range-sum-of-bst/</link>
					<comments>https://zxi.mytechroad.com/blog/tree/leetcode-938-range-sum-of-bst/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 11 Nov 2018 07:41:47 +0000</pubDate>
				<category><![CDATA[Tree]]></category>
		<category><![CDATA[BST]]></category>
		<category><![CDATA[inorder]]></category>
		<category><![CDATA[range]]></category>
		<category><![CDATA[range sum]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=4285</guid>

					<description><![CDATA[<p>Problem Given the root node of a binary search tree, return the sum of values of all nodes with value between L and R (inclusive). The binary search tree is guaranteed&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/tree/leetcode-938-range-sum-of-bst/">花花酱 LeetCode 938. Range Sum of BST</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h1><strong>Problem</strong></h1>
<p>Given the <code>root</code> node of a binary search tree, return the sum of values of all nodes with value between <code>L</code> and <code>R</code> (inclusive).</p>
<p>The binary search tree is guaranteed to have unique values.</p>
<p><strong>Example 1:</strong></p>
<pre class="crayon:false"><strong>Input: </strong>root = <span id="example-input-1-1">[10,5,15,3,7,null,18]</span>, L = <span id="example-input-1-2">7</span>, R = <span id="example-input-1-3">15</span>
<strong>Output: </strong><span id="example-output-1">32</span>
</pre>
<p><strong>Example 2:</strong></p>
<pre class="crayon:false"><strong>Input: </strong>root = <span id="example-input-2-1">[10,5,15,3,7,13,18,1,null,6]</span>, L = <span id="example-input-2-2">6</span>, R = <span id="example-input-2-3">10</span>
<strong>Output: </strong><span id="example-output-2">23</span>
</pre>
<p><strong>Note:</strong></p>
<ol>
<li>The number of nodes in the tree is at most <code>10000</code>.</li>
<li>The final answer is guaranteed to be less than <code>2^31</code>.</li>
</ol>
<h1>Solution: In-order traversal</h1>
<p>Time complexity: O(n)</p>
<p>Space complexity: O(n)</p>
<p><div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua, running time: 72 ms
class Solution {
public:
  int rangeSumBST(TreeNode* root, int L, int R) {
    if (!root) return 0;
    int sum = 0;
    if (root-&gt;val &gt;= L) sum += rangeSumBST(root-&gt;left, L, R);
    if (root-&gt;val &gt;= L &amp;&amp; root-&gt;val &lt;= R) sum += root-&gt;val;
    if (root-&gt;val &lt;= R) sum += rangeSumBST(root-&gt;right, L, R);
    return sum;
  }
};</pre><p></div></div></p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/tree/leetcode-938-range-sum-of-bst/">花花酱 LeetCode 938. Range Sum of BST</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/tree/leetcode-938-range-sum-of-bst/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 910. Smallest Range II</title>
		<link>https://zxi.mytechroad.com/blog/greedy/leetcode-910-smallest-range-ii/</link>
					<comments>https://zxi.mytechroad.com/blog/greedy/leetcode-910-smallest-range-ii/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Wed, 26 Sep 2018 15:35:50 +0000</pubDate>
				<category><![CDATA[Greedy]]></category>
		<category><![CDATA[greedy]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[range]]></category>
		<category><![CDATA[smallest]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=4081</guid>

					<description><![CDATA[<p>Problem Given an array A of integers, for each integer A[i] we need to choose either x = -K or x = K, and add x to A[i] (only once). After this process, we have some array B.&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/greedy/leetcode-910-smallest-range-ii/">花花酱 LeetCode 910. Smallest Range 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[<h1><strong>Problem</strong></h1>
<p>Given an array <code>A</code> of integers, for each integer <code>A[i]</code> we need to choose <strong>either <code>x = -K</code> or <code>x = K</code></strong>, and add <code>x</code> to <code>A[i] <strong>(only once)</strong></code>.</p>
<p>After this process, we have some array <code>B</code>.</p>
<p>Return the smallest possible difference between the maximum value of <code>B</code> and the minimum value of <code>B</code>.</p>
<p><strong>Example 1:</strong></p>
<pre class="crayon:false"><strong>Input: </strong>A = <span id="example-input-1-1">[1]</span>, K = <span id="example-input-1-2">0</span>
<strong>Output: </strong><span id="example-output-1">0</span>
<strong>Explanation</strong>: B = [1]
</pre>
<p><strong>Example 2:</strong></p>
<pre class="crayon:false"><strong>Input: </strong>A = <span id="example-input-2-1">[0,10]</span>, K = <span id="example-input-2-2">2</span>
<strong>Output: </strong><span id="example-output-2">6
</span><strong>Explanation</strong>: B = [2,8]
</pre>
<p><strong>Example 3:</strong></p>
<pre class="crayon:false"><strong>Input: </strong>A = <span id="example-input-3-1">[1,3,6]</span>, K = <span id="example-input-3-2">3</span>
<strong>Output: </strong><span id="example-output-3">3</span>
<strong>Explanation</strong>: B = [4,6,3]
</pre>
<p><strong>Note:</strong></p>
<ol>
<li><code>1 &lt;= A.length &lt;= 10000</code></li>
<li><code>0 &lt;= A[i] &lt;= 10000</code></li>
<li><code>0 &lt;= K &lt;= 10000</code></li>
</ol>
<h1><strong>Solution: Greedy</strong></h1>
<p>Sort the array and compare adjacent numbers.</p>
<p>Time complexity: O(nlogn)</p>
<p>Space complexity: O(1)</p>
<p><div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  int smallestRangeII(vector&lt;int&gt;&amp; A, int K) {    
    sort(begin(A), end(A));    
    int ans = A.back() - A.front();
    for (int i = 1; i &lt; A.size(); ++i) {      
      int l = min(A.front() + K, A[i] - K);
      int h = max(A.back() - K, A[i - 1] + K);
      ans = min(ans, h - l);
    }
    return ans;
  }
};</pre><p></div><h2 class="tabtitle">Python3</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag"># Author: Huahua
class Solution:
  def smallestRangeII(self, A, K):
    A.sort()
    ans = A[-1] - A[0]
    for a, b in zip(A[0:-1], A[1:]):
      l = min(A[0] + K, b - K)
      h = max(A[-1] - K, a + K)
      ans = min(ans, h - l)
    return ans</pre><p></div></div></p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/greedy/leetcode-910-smallest-range-ii/">花花酱 LeetCode 910. Smallest Range 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/greedy/leetcode-910-smallest-range-ii/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 908. Smallest Range I</title>
		<link>https://zxi.mytechroad.com/blog/math/leetcode-908-smallest-range-i/</link>
					<comments>https://zxi.mytechroad.com/blog/math/leetcode-908-smallest-range-i/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 24 Sep 2018 06:02:15 +0000</pubDate>
				<category><![CDATA[Math]]></category>
		<category><![CDATA[all pairs]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[range]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=4067</guid>

					<description><![CDATA[<p>Problem Given an array A of integers, for each integer A[i] we may choose any x with -K &#60;= x &#60;= K, and add xto A[i]. After this process, we have some array B. Return&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/math/leetcode-908-smallest-range-i/">花花酱 LeetCode 908. Smallest Range I</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h1><strong>Problem</strong></h1>
<p>Given an array <code>A</code> of integers, for each integer <code>A[i]</code> we may choose any <code>x</code> with <code>-K &lt;= x &lt;= K</code>, and add <code>x</code>to <code>A[i]</code>.</p>
<p>After this process, we have some array <code>B</code>.</p>
<p>Return the smallest possible difference between the maximum value of <code>B</code> and the minimum value of <code>B</code>.</p>
<div>
<p><strong>Example 1:</strong></p>
<pre class="crayon:false"><strong>Input: </strong>A = <span id="example-input-1-1">[1]</span>, K = <span id="example-input-1-2">0</span>
<strong>Output: </strong><span id="example-output-1">0
<strong>Explanation</strong>: B = [1]</span>
</pre>
<div>
<p><strong>Example 2:</strong></p>
<pre class="crayon:false"><strong>Input: </strong>A = <span id="example-input-2-1">[0,10]</span>, K = <span id="example-input-2-2">2</span>
<strong>Output: </strong><span id="example-output-2">6
</span><span id="example-output-1"><strong>Explanation</strong>: B = [2,8]</span>
</pre>
<div>
<p><strong>Example 3:</strong></p>
<pre class="crayon:false "><strong>Input: </strong>A = <span id="example-input-3-1">[1,3,6]</span>, K = <span id="example-input-3-2">3</span>
<strong>Output: </strong><span id="example-output-3">0
</span><span id="example-output-1"><strong>Explanation</strong>: B = [3,3,3] or B = [4,4,4]</span>
</pre>
<p><strong>Note:</strong></p>
<ol>
<li><code>1 &lt;= A.length &lt;= 10000</code></li>
<li><code>0 &lt;= A[i] &lt;= 10000</code></li>
<li><code>0 &lt;= K &lt;= 10000</code></li>
</ol>
<h1>Solution 0: Brute Force (TLE)</h1>
<p>Try all pairs</p>
<p>Time complexity: O(n^2)</p>
<p>Space complexity: O(1)</p>
<h1>Solution 1: Math</h1>
<p>Time complexity: O(n)</p>
<p>Space complexity: O(1)</p>
<p>Find the min/max element of the array.</p>
<p>min + k v.s. max &#8211; k</p>
<p>ans = max(0, (max &#8211; min) &#8211; 2 * k))</p>
<p><div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  int smallestRangeI(vector&lt;int&gt;&amp; A, int K) {
    int a_min = *min_element(begin(A), end(A));
    int a_max = *max_element(begin(A), end(A));
    return max(0, (a_max - a_min) - 2 * K);
  }
};</pre><p></div><h2 class="tabtitle">Python3</h2>
<div class="tabcontent">
</p><pre class="crayon-plain-tag"># Author: Huahua, 72 ms
class Solution:
  def smallestRangeI(self, A, K):
    return max(0, max(A) - min(A) - 2 * K);</pre><p></div></div></p>
</div>
</div>
</div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/math/leetcode-908-smallest-range-i/">花花酱 LeetCode 908. Smallest Range I</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/math/leetcode-908-smallest-range-i/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 598. Range Addition II</title>
		<link>https://zxi.mytechroad.com/blog/geometry/leetcode-598-range-addition-ii/</link>
					<comments>https://zxi.mytechroad.com/blog/geometry/leetcode-598-range-addition-ii/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Wed, 21 Mar 2018 04:04:47 +0000</pubDate>
				<category><![CDATA[Geometry]]></category>
		<category><![CDATA[easy]]></category>
		<category><![CDATA[matrix]]></category>
		<category><![CDATA[range]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=2255</guid>

					<description><![CDATA[<p>Problem https://leetcode.com/problems/range-addition-ii/description/ Given an m * n matrix M initialized with all 0&#8216;s and several update operations. Operations are represented by a 2D array, and each operation is&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/geometry/leetcode-598-range-addition-ii/">花花酱 LeetCode 598. Range Addition 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[<h1><strong>Problem</strong></h1>
<p><a href="https://leetcode.com/problems/range-addition-ii/description/">https://leetcode.com/problems/range-addition-ii/description/</a></p>
<p>Given an m * n matrix <b>M</b> initialized with all <b>0</b>&#8216;s and several update operations.</p>
<p>Operations are represented by a 2D array, and each operation is represented by an array with two <b>positive</b>integers <b>a</b> and <b>b</b>, which means <b>M[i][j]</b> should be <b>added by one</b> for all <b>0 &lt;= i &lt; a</b> and <b>0 &lt;= j &lt; b</b>.</p>
<p>You need to count and return the number of maximum integers in the matrix after performing all the operations.</p>
<p><b>Example 1:</b></p>
<pre class="crayon:false"><b>Input:</b> 
m = 3, n = 3
operations = [[2,2],[3,3]]
<b>Output:</b> 4
<b>Explanation:</b> 
Initially, M = 
[[0, 0, 0],
 [0, 0, 0],
 [0, 0, 0]]

After performing [2,2], M = 
[[1, 1, 0],
 [1, 1, 0],
 [0, 0, 0]]

After performing [3,3], M = 
[[2, 2, 1],
 [2, 2, 1],
 [1, 1, 1]]

So the maximum integer in M is 2, and there are four of it in M. So return 4.
</pre>
<p><b>Note:</b></p>
<ol>
<li>The range of m and n is [1,40000].</li>
<li>The range of a is [1,m], and the range of b is [1,n].</li>
<li>The range of operations size won&#8217;t exceed 10,000.</li>
</ol>
<h1>Solution:</h1>
<p>Time Complexity: O(n)</p>
<p>Space Complexity: O(1)</p>
<p>C++</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 9 ms
class Solution {
public:
  int maxCount(int m, int n, vector&lt;vector&lt;int&gt;&gt;&amp; ops) {
    for (const auto&amp; range : ops) {
      m = min(m, range[0]);
      n = min(n, range[1]);
    }
    return m * n;
  }
};</pre><p>&nbsp;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/geometry/leetcode-598-range-addition-ii/">花花酱 LeetCode 598. Range Addition 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/geometry/leetcode-598-range-addition-ii/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 731. My Calendar II &#8211; 花花酱</title>
		<link>https://zxi.mytechroad.com/blog/geometry/leetcode-731-my-calendar-ii/</link>
					<comments>https://zxi.mytechroad.com/blog/geometry/leetcode-731-my-calendar-ii/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 20 Nov 2017 02:24:40 +0000</pubDate>
				<category><![CDATA[Easy]]></category>
		<category><![CDATA[Geometry]]></category>
		<category><![CDATA[overlap]]></category>
		<category><![CDATA[range]]></category>
		<category><![CDATA[sweep line]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=864</guid>

					<description><![CDATA[<p>Problem:  Implement a MyCalendarTwo class to store your events. A new event can be added if adding the event will not cause a triple booking. Your class will have&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/geometry/leetcode-731-my-calendar-ii/">花花酱 LeetCode 731. My Calendar II &#8211; 花花酱</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/rRMdxFA-8G4?feature=oembed" frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen></iframe></p>
<p><strong>Problem: </strong></p>
<p>Implement a <code>MyCalendarTwo</code> class to store your events. A new event can be added if adding the event will not cause a <b>triple</b> booking.</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>triple booking</i> happens when <b>three</b> events have some non-empty intersection (ie., there is some time that is common to all 3 events.)</p>
<p>For each call to the method <code>MyCalendar.book</code>, return <code>true</code> if the event can be added to the calendar successfully without causing a <b>triple</b> booking. Otherwise, return <code>false</code> and do not add the event to the calendar.</p>
<p>Your class will be called like this: <code>MyCalendar cal = new MyCalendar();</code> <code>MyCalendar.book(start, end)</code></p>
<p><b>Example 1:</b></p><pre class="crayon-plain-tag">MyCalendar();
MyCalendar.book(10, 20); // returns true
MyCalendar.book(50, 60); // returns true
MyCalendar.book(10, 40); // returns true
MyCalendar.book(5, 15); // returns false
MyCalendar.book(5, 10); // returns true
MyCalendar.book(25, 55); // returns true
Explanation&lt;b&gt;:&lt;/b&gt; 
The first two events can be booked.  The third event can be double booked.
The fourth event (5, 15) can't be booked, because it would result in a triple booking.
The fifth event (5, 10) can be booked, as it does not use time 10 which is already double booked.
The sixth event (25, 55) can be booked, as the time in [25, 40) will be double booked with the third event;
the time [40, 50) will be single booked, and the time [50, 55) will be double booked with the second event.</pre><p><b>Note:</b></p>
<p>&nbsp;</p>
<ul>
<li>The number of calls to <code>MyCalendar.book</code> per test case will be at most <code>1000</code>.</li>
<li>In calls to <code>MyCalendar.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>Brute Force</p>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/731-ep113-1.png"><img class="alignnone size-full wp-image-875" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/731-ep113-1.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/731-ep113-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/731-ep113-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/731-ep113-1-768x432.png 768w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/731-ep113-1-624x351.png 624w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<p><b style="font-size: 1rem;">Solution1:</b></p>
<p>Brute Force</p>
<p>Time Complexity: O(n^2)</p>
<p>Space Complexity: O(n)</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 82 ms
class MyCalendarTwo {
public:
    MyCalendarTwo() {}
    
    bool book(int start, int end) {
        for (const auto&amp; kv : overlaps_)
            if (max(start, kv.first) &lt; min(end, kv.second)) return false;
        
        for (const auto&amp; kv : booked_) {
            const int ss = max(start, kv.first);
            const int ee = min(end, kv.second);
            if (ss &lt; ee) overlaps_.emplace_back(ss, ee);
        }
        
        booked_.emplace_back(start, end);
        return true;
    }
private:
    vector&lt;pair&lt;int, int&gt;&gt; booked_;
    vector&lt;pair&lt;int, int&gt;&gt; overlaps_;
};</pre><p>&nbsp;</p>
<p>Java</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 156 ms
class MyCalendarTwo {
    
    private List&lt;int[]&gt; booked_;
    private List&lt;int[]&gt; overlaps_;

    public MyCalendarTwo() {
        booked_ = new ArrayList&lt;&gt;();
        overlaps_ = new ArrayList&lt;&gt;();
    }
    
    public boolean book(int start, int end) {
        for (int[] range : overlaps_)
            if (Math.max(range[0], start) &lt; Math.min(range[1], end)) 
                return false;
        
        for (int[] range : booked_) {
            int ss = Math.max(range[0], start);
            int ee = Math.min(range[1], end);
            if (ss &lt; ee) overlaps_.add(new int[]{ss, ee});
        }
        
        booked_.add(new int[]{start, end});
        return true;
    }

}</pre><p>Python</p><pre class="crayon-plain-tag">"""
Author: Huahua
Runtime: 638 ms
"""
class MyCalendarTwo:

    def __init__(self):
        self.booked_ = []
        self.overlaps_ = []

    def book(self, start, end):
        for s, e in self.overlaps_:
            if start &lt; e and end &gt; s: return False
        
        for s, e in self.booked_:            
            if start &lt; e and end &gt; s: 
                self.overlaps_.append([max(start, s), min(end, e)])
        
        self.booked_.append([start, end])
        return True</pre><p>&nbsp;</p>
<p><strong>Solution 2:</strong></p>
<p>Counting</p>
<p>Time Complexity: O(n^2logn)</p>
<p>Space Complexity: O(n)</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 212 ms
class MyCalendarTwo {
public:
    MyCalendarTwo() {}
    
    bool book(int start, int end) {
        ++delta_[start];
        --delta_[end];
        int count = 0;
        for (const auto&amp; kv : delta_) {
            count += kv.second;
            if (count == 3) {
                --delta_[start];
                ++delta_[end];
                return false;
            }
            if (kv.first &gt; end) break;
        }
        return true;
    }
private:
    map&lt;int, int&gt; delta_;
};</pre><p>&nbsp;</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/data-structure/leetcode-715-range-module/">[解题报告] LeetCode 715. Range Module</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/geometry/leetcode-56-merge-intervals/">[解题报告] LeetCode 56. Merge Intervals</a></li>
<li><a href="http://zxi.mytechroad.com/blog/geometry/leetcode-699-falling-squares/">[解题报告] LeetCode 699. Falling Squares</a></li>
</ul>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/geometry/leetcode-731-my-calendar-ii/">花花酱 LeetCode 731. My Calendar II &#8211; 花花酱</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-731-my-calendar-ii/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 729. My Calendar I</title>
		<link>https://zxi.mytechroad.com/blog/algorithms/binary-search/leetcode-729-my-calendar-i/</link>
					<comments>https://zxi.mytechroad.com/blog/algorithms/binary-search/leetcode-729-my-calendar-i/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 19 Nov 2017 16:54:20 +0000</pubDate>
				<category><![CDATA[Binary Search]]></category>
		<category><![CDATA[Medium]]></category>
		<category><![CDATA[range]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=855</guid>

					<description><![CDATA[<p>Problem: Implement a MyCalendar class to store your events. A new event can be added if adding the event will not cause a double booking. Your class&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/algorithms/binary-search/leetcode-729-my-calendar-i/">花花酱 LeetCode 729. My Calendar I</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/seQnf-5hlBo?feature=oembed" frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen></iframe></p>
<p><strong>Problem:</strong></p>
<p>Implement a <code>MyCalendar</code> class to store your events. A new event can be added if adding the event will not cause a double booking.</p>
<p>Your class will have the 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>double booking</i> happens when two events have some non-empty intersection (ie., there is some time that is common to both events.)</p>
<p>For each call to the method <code>MyCalendar.book</code>, return <code>true</code> if the event can be added to the calendar successfully without causing a double booking. Otherwise, return <code>false</code> and do not add the event to the calendar.</p>
<p>Your class will be called like this: <code>MyCalendar cal = new MyCalendar();</code> <code>MyCalendar.book(start, end)</code></p>
<p><b>Example 1:</b></p><pre class="crayon-plain-tag">MyCalendar();
MyCalendar.book(10, 20); // returns true
MyCalendar.book(15, 25); // returns false
MyCalendar.book(20, 30); // returns true
Explanation: 
The first event can be booked.  The second can't because time 15 is already booked by another event.
The third event can be booked, as the first event takes every time less than 20, but not including 20.</pre><p><b>Note:</b></p>
<p>&nbsp;</p>
<ul>
<li>The number of calls to <code>MyCalendar.book</code> per test case will be at most <code>1000</code>.</li>
<li>In calls to <code>MyCalendar.book(start, end)</code>, <code>start</code> and <code>end</code> are integers in the range <code>[0, 10^9]</code>.</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>Binary Search</p>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/729-ep112.png"><img class="alignnone size-full wp-image-877" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/729-ep112.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/729-ep112.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/729-ep112-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/729-ep112-768x432.png 768w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/729-ep112-624x351.png 624w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<p><strong>Solution1:</strong></p>
<p>Brute Force: O(n^2)</p>
<p>C++</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 99 ms
class MyCalendar {
public:
    MyCalendar() {}
    
    bool book(int start, int end) {        
        for (const auto&amp; event : booked_) {
            int s = event.first;
            int e = event.second;          
            if (max(s, start) &lt; min(e, end)) return false;
        }       
        booked_.emplace_back(start, end);        
        return true;
    }
private:
    vector&lt;pair&lt;int, int&gt;&gt; booked_;
};</pre><p><strong>Solution 2:</strong></p>
<p>Binary Search O(nlogn)</p>
<p>C++</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 82 ms
class MyCalendar {
public:
    MyCalendar() {}
    
    bool book(int start, int end) {        
        auto it = booked_.lower_bound(start);
        if (it != booked_.cend() &amp;&amp; it-&gt;first &lt; end)
            return false;        
        if (it != booked_.cbegin() &amp;&amp; (--it)-&gt;second &gt; start)
            return false;        
        booked_[start] = end;
        return true;
    }
private:
    map&lt;int, int&gt; booked_;
};</pre><p>Java</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 170 ms
class MyCalendar {
    TreeMap&lt;Integer, Integer&gt; booked_;
    public MyCalendar() {
        booked_ = new TreeMap&lt;&gt;();
    }
    
    public boolean book(int start, int end) {
        Integer lb = booked_.floorKey(start);
        if (lb != null &amp;&amp; booked_.get(lb) &gt; start) return false;
        Integer ub = booked_.ceilingKey(start);
        if (ub != null &amp;&amp; ub &lt; end) return false;

        booked_.put(start, end);
        return true;
    }
}</pre><p>&nbsp;</p>
<p><strong>Related Problems:</strong></p>
<ul>
<li><a href="http://zxi.mytechroad.com/blog/geometry/leetcode-731-my-calendar-ii/">[解题报告] LeetCode 731. My Calendar II</a></li>
<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/geometry/leetcode-699-falling-squares/">[解题报告] LeetCode 699. Falling Squares</a></li>
<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>
</ul>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/algorithms/binary-search/leetcode-729-my-calendar-i/">花花酱 LeetCode 729. My Calendar I</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-729-my-calendar-i/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>
