<?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>priority queue &#8211; Huahua&#8217;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/tag/priority-queue/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog</link>
	<description></description>
	<lastBuildDate>Fri, 28 Mar 2025 03:46:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.7.2</generator>

<image>
	<url>https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/cropped-photo-32x32.jpg</url>
	<title>priority queue &#8211; Huahua&#8217;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>花花酱 LeetCode 3408. Design Task Manager</title>
		<link>https://zxi.mytechroad.com/blog/priority-queue/leetcode-3408-design-task-manager/</link>
					<comments>https://zxi.mytechroad.com/blog/priority-queue/leetcode-3408-design-task-manager/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Fri, 28 Mar 2025 03:45:03 +0000</pubDate>
				<category><![CDATA[Priority Queue]]></category>
		<category><![CDATA[hashtable]]></category>
		<category><![CDATA[iterator]]></category>
		<category><![CDATA[map]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[priority queue]]></category>
		<category><![CDATA[treemap]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=10229</guid>

					<description><![CDATA[pq_ 使用std::map充当优先队列，存储(priority, taskId) -> userId m_ 使用std::unordered_map，存储taskId -> pq_的迭代器 所有操作都是O(logn) [crayon-67eaa887412e8385336154/]]]></description>
										<content:encoded><![CDATA[
<ol class="wp-block-list"><li>pq_ 使用std::map充当优先队列，存储(priority, taskId) -> userId</li><li>m_ 使用std::unordered_map，存储taskId -> pq_的迭代器</li></ol>



<p>所有操作都是O(logn)</p>



<pre class="urvanov-syntax-highlighter-plain-tag">class TaskManager {
public:
    TaskManager(vector&lt;vector&lt;int&gt;&gt;&amp; tasks) {
      for (const auto&amp; task : tasks)
        add(task[0], task[1], task[2]);
    }

    void add(int userId, int taskId, int priority) {
      m_[taskId] = pq_.emplace(make_pair(priority, taskId), userId).first;
    }
    
    void edit(int taskId, int newPriority) {
      const int userId = m_[taskId]-&gt;second;
      rmv(taskId);
      add(userId, taskId, newPriority);
    }
    
    void rmv(int taskId) {
      auto it = m_.find(taskId);
      pq_.erase(it-&gt;second);
      m_.erase(it);
    }
    
    int execTop() {
      if (pq_.empty()) return -1;
      auto it = pq_.rbegin();
      const int userId = it-&gt;second;
      const int taskId = (it-&gt;first.second);
      rmv(taskId);
      return userId;
    }
  private:
    map&lt;std::pair&lt;int,int&gt;, int&gt; pq_; // (priority, taskId) -&gt; userId;
    unordered_map&lt;int, map&lt;std::pair&lt;int,int&gt;, int&gt;::iterator&gt; m_; // taskId -&gt; pq iterator
};</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/priority-queue/leetcode-3408-design-task-manager/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2558. Take Gifts From the Richest Pile</title>
		<link>https://zxi.mytechroad.com/blog/heap/leetcode-2558-take-gifts-from-the-richest-pile/</link>
					<comments>https://zxi.mytechroad.com/blog/heap/leetcode-2558-take-gifts-from-the-richest-pile/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 05 Feb 2023 05:12:41 +0000</pubDate>
				<category><![CDATA[Heap]]></category>
		<category><![CDATA[easy]]></category>
		<category><![CDATA[max heap]]></category>
		<category><![CDATA[priority queue]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9923</guid>

					<description><![CDATA[You are given an integer array&#160;gifts&#160;denoting the number of gifts in various piles. Every second, you do the following: Choose the pile with the maximum&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You are given an integer array&nbsp;<code>gifts</code>&nbsp;denoting the number of gifts in various piles. Every second, you do the following:</p>



<ul class="wp-block-list"><li>Choose the pile with the maximum number of gifts.</li><li>If there is more than one pile with the maximum number of gifts, choose any.</li><li>Leave behind the floor of the square root of the number of gifts in the pile. Take the rest of the gifts.</li></ul>



<p>Return&nbsp;<em>the number of gifts remaining after&nbsp;</em><code>k</code><em>&nbsp;seconds.</em></p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> gifts = [25,64,9,4,100], k = 4
<strong>Output:</strong> 29
<strong>Explanation:</strong> 
The gifts are taken in the following way:
- In the first second, the last pile is chosen and 10 gifts are left behind.
- Then the second pile is chosen and 8 gifts are left behind.
- After that the first pile is chosen and 5 gifts are left behind.
- Finally, the last pile is chosen again and 3 gifts are left behind.
The final remaining gifts are [5,8,9,4,3], so the total number of gifts remaining is 29.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> gifts = [1,1,1,1], k = 4
<strong>Output:</strong> 4
<strong>Explanation:</strong> 
In this case, regardless which pile you choose, you have to leave behind 1 gift in each pile. 
That is, you can't take any pile with you. 
So, the total gifts remaining are 4.
</pre>



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



<ul class="wp-block-list"><li><code>1 &lt;= gifts.length &lt;= 10<sup>3</sup></code></li><li><code>1 &lt;= gifts[i] &lt;= 10<sup>9</sup></code></li><li><code>1 &lt;= k &lt;= 10<sup>3</sup></code></li></ul>



<h2 class="wp-block-heading"><strong>Solution: Priority Queue</strong></h2>



<p>Keep all numbers in a priority queue (max heap), each time extract the top one (largest one), then put num  &#8211; sqrt(num) back to the queue.</p>



<p>Tip: We can early return if all the numbers become 1.</p>



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  long long pickGifts(vector&lt;int&gt;&amp; gifts, int k) {
    long long ans = accumulate(begin(gifts), end(gifts), 0LL);
    priority_queue&lt;int&gt; q(begin(gifts), end(gifts));
    while (k-- &amp;&amp; q.top() &gt; 1) {
      int cur = q.top(); q.pop();
      int next = sqrt(cur);
      ans -= (cur - next);
      q.push(next);
    }
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/heap/leetcode-2558-take-gifts-from-the-richest-pile/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2233. Maximum Product After K Increments</title>
		<link>https://zxi.mytechroad.com/blog/priority-queue/leetcode-2233-maximum-product-after-k-increments/</link>
					<comments>https://zxi.mytechroad.com/blog/priority-queue/leetcode-2233-maximum-product-after-k-increments/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 10 Apr 2022 06:38:03 +0000</pubDate>
				<category><![CDATA[Priority Queue]]></category>
		<category><![CDATA[greedy]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[priority queue]]></category>
		<category><![CDATA[product]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9640</guid>

					<description><![CDATA[You are given an array of non-negative integers&#160;nums&#160;and an integer&#160;k. In one operation, you may choose&#160;any&#160;element from&#160;nums&#160;and&#160;increment&#160;it by&#160;1. Return&#160;the&#160;maximum&#160;product&#160;of&#160;nums&#160;after&#160;at most&#160;k&#160;operations.&#160;Since the answer may be very&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You are given an array of non-negative integers&nbsp;<code>nums</code>&nbsp;and an integer&nbsp;<code>k</code>. In one operation, you may choose&nbsp;<strong>any</strong>&nbsp;element from&nbsp;<code>nums</code>&nbsp;and&nbsp;<strong>increment</strong>&nbsp;it by&nbsp;<code>1</code>.</p>



<p>Return<em>&nbsp;the&nbsp;<strong>maximum</strong>&nbsp;<strong>product</strong>&nbsp;of&nbsp;</em><code>nums</code><em>&nbsp;after&nbsp;<strong>at most</strong>&nbsp;</em><code>k</code><em>&nbsp;operations.&nbsp;</em>Since the answer may be very large, return it&nbsp;<strong>modulo</strong>&nbsp;<code>10<sup>9</sup>&nbsp;+ 7</code>.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [0,4], k = 5
<strong>Output:</strong> 20
<strong>Explanation:</strong> Increment the first number 5 times.
Now nums = [5, 4], with a product of 5 * 4 = 20.
It can be shown that 20 is maximum product possible, so we return 20.
Note that there may be other ways to increment nums to have the maximum product.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [6,3,3,2], k = 2
<strong>Output:</strong> 216
<strong>Explanation:</strong> Increment the second number 1 time and increment the fourth number 1 time.
Now nums = [6, 4, 3, 3], with a product of 6 * 4 * 3 * 3 = 216.
It can be shown that 216 is maximum product possible, so we return 216.
Note that there may be other ways to increment nums to have the maximum product.
</pre>



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



<ul class="wp-block-list"><li><code>1 &lt;= nums.length, k &lt;= 10<sup>5</sup></code></li><li><code>0 &lt;= nums[i] &lt;= 10<sup>6</sup></code></li></ul>



<h2 class="wp-block-heading"><strong>Solution: priority queue</strong></h2>



<p>Always increment the smallest number. Proof?</p>



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  int maximumProduct(vector&lt;int&gt;&amp; nums, int k) {
    constexpr int kMod = 1e9 + 7;
    priority_queue&lt;int, vector&lt;int&gt;, greater&lt;int&gt;&gt; q(begin(nums), end(nums));
    while (k--) {
      const int n = q.top(); 
      q.pop();
      q.push(n + 1);
    }
    long long ans = 1;
    while (!q.empty()) {
      ans *= q.top(); q.pop();
      ans %= kMod;
    }
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/priority-queue/leetcode-2233-maximum-product-after-k-increments/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1882. Process Tasks Using Servers</title>
		<link>https://zxi.mytechroad.com/blog/simulation/leetcode-1882-process-tasks-using-servers/</link>
					<comments>https://zxi.mytechroad.com/blog/simulation/leetcode-1882-process-tasks-using-servers/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 09 Aug 2021 01:07:18 +0000</pubDate>
				<category><![CDATA[Simulation]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[priority queue]]></category>
		<category><![CDATA[schedule]]></category>
		<category><![CDATA[simulation]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8527</guid>

					<description><![CDATA[You are given two&#160;0-indexed&#160;integer arrays&#160;servers&#160;and&#160;tasks&#160;of lengths&#160;n​​​​​​ and&#160;m​​​​​​ respectively.&#160;servers[i]&#160;is the&#160;weight&#160;of the&#160;i​​​​​​th​​​​ server, and&#160;tasks[j]&#160;is the&#160;time needed&#160;to process the&#160;j​​​​​​th​​​​ task&#160;in seconds. Tasks are assigned to the servers using&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You are given two&nbsp;<strong>0-indexed</strong>&nbsp;integer arrays&nbsp;<code>servers</code>&nbsp;and&nbsp;<code>tasks</code>&nbsp;of lengths&nbsp;<code>n</code>​​​​​​ and&nbsp;<code>m</code>​​​​​​ respectively.&nbsp;<code>servers[i]</code>&nbsp;is the&nbsp;<strong>weight</strong>&nbsp;of the&nbsp;<code>i<sup>​​​​​​th</sup></code>​​​​ server, and&nbsp;<code>tasks[j]</code>&nbsp;is the&nbsp;<strong>time needed</strong>&nbsp;to process the&nbsp;<code>j<sup>​​​​​​th</sup></code>​​​​ task&nbsp;<strong>in seconds</strong>.</p>



<p>Tasks are assigned to the servers using a&nbsp;<strong>task queue</strong>. Initially, all servers are free, and the queue is&nbsp;<strong>empty</strong>.</p>



<p>At second&nbsp;<code>j</code>, the&nbsp;<code>j<sup>th</sup></code>&nbsp;task is&nbsp;<strong>inserted</strong>&nbsp;into the queue (starting with the&nbsp;<code>0<sup>th</sup></code>&nbsp;task being inserted at second&nbsp;<code>0</code>). As long as there are free servers and the queue is not empty, the task in the front of the queue will be assigned to a free server with the&nbsp;<strong>smallest weight</strong>, and in case of a tie, it is assigned to a free server with the&nbsp;<strong>smallest index</strong>.</p>



<p>If there are no free servers and the queue is not empty, we wait until a server becomes free and immediately assign the next task. If multiple servers become free at the same time, then multiple tasks from the queue will be assigned&nbsp;<strong>in order of insertion</strong>&nbsp;following the weight and index priorities above.</p>



<p>A server that is assigned task&nbsp;<code>j</code>&nbsp;at second&nbsp;<code>t</code>&nbsp;will be free again at second&nbsp;<code>t + tasks[j]</code>.</p>



<p>Build an array&nbsp;<code>ans</code>​​​​ of length&nbsp;<code>m</code>, where&nbsp;<code>ans[j]</code>&nbsp;is the&nbsp;<strong>index</strong>&nbsp;of the server the&nbsp;<code>j<sup>​​​​​​th</sup></code>&nbsp;task will be assigned to.</p>



<p>Return&nbsp;<em>the array&nbsp;</em><code>ans</code>​​​​.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> servers = [3,3,2], tasks = [1,2,3,2,1,2]
<strong>Output:</strong> [2,2,0,2,1,2]
<strong>Explanation: </strong>Events in chronological order go as follows:
- At second 0, task 0 is added and processed using server 2 until second 1.
- At second 1, server 2 becomes free. Task 1 is added and processed using server 2 until second 3.
- At second 2, task 2 is added and processed using server 0 until second 5.
- At second 3, server 2 becomes free. Task 3 is added and processed using server 2 until second 5.
- At second 4, task 4 is added and processed using server 1 until second 5.
- At second 5, all servers become free. Task 5 is added and processed using server 2 until second 7.</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> servers = [5,1,4,3,2], tasks = [2,1,2,4,5,2,1]
<strong>Output:</strong> [1,4,1,4,1,3,2]
<strong>Explanation: </strong>Events in chronological order go as follows: 
- At second 0, task 0 is added and processed using server 1 until second 2.
- At second 1, task 1 is added and processed using server 4 until second 2.
- At second 2, servers 1 and 4 become free. Task 2 is added and processed using server 1 until second 4. 
- At second 3, task 3 is added and processed using server 4 until second 7.
- At second 4, server 1 becomes free. Task 4 is added and processed using server 1 until second 9. 
- At second 5, task 5 is added and processed using server 3 until second 7.
- At second 6, task 6 is added and processed using server 2 until second 7.
</pre>



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



<ul class="wp-block-list"><li><code>servers.length == n</code></li><li><code>tasks.length == m</code></li><li><code>1 &lt;= n, m &lt;= 2 * 10<sup>5</sup></code></li><li><code>1 &lt;= servers[i], tasks[j] &lt;= 2 * 10<sup>5</sup></code></li></ul>



<h2 class="wp-block-heading"><strong>Solution: Simulation / Priority Queue</strong></h2>



<p>Two priority queues, one for free servers, another for releasing events.<br>One FIFO queue for tasks to schedule.</p>



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  vector&lt;int&gt; assignTasks(vector&lt;int&gt;&amp; servers, vector&lt;int&gt;&amp; tasks) {
    const int n = servers.size();
    const int m = tasks.size();
    using P = pair&lt;long, int&gt;;
    priority_queue&lt;P, vector&lt;P&gt;, greater&lt;P&gt;&gt; frees, release;
    for (int i = 0; i &lt; n; ++i)
      frees.emplace(servers[i], i);    
    vector&lt;int&gt; ans(m);
    queue&lt;int&gt; q;
    int l = 0;
    long t = 0;
    int count = 0;
    while (count != m) {      
      // Release servers.      
      while (!release.empty() &amp;&amp; release.top().first &lt;= t) {
        auto [rt, i] = release.top(); release.pop();
        frees.emplace(servers[i], i);        
      }
      // Enqueue tasks.
      while (l &lt; m &amp;&amp; l &lt;= t) q.push(l++);
      // Schedule tasks.
      while (q.size() &amp;&amp; frees.size()) {
        const int j = q.front(); q.pop();
        auto [w, i] = frees.top(); frees.pop();
        release.emplace(t + tasks[j], i);
        ans[j] = i;
        ++count;
      }
      // Advance time.
      if (frees.empty() &amp;&amp; !release.empty()) {             
        t = release.top().first;
      } else {
        ++t;
      }
    }
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/simulation/leetcode-1882-process-tasks-using-servers/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1851. Minimum Interval to Include Each Query</title>
		<link>https://zxi.mytechroad.com/blog/priority-queue/leetcode-1851-minimum-interval-to-include-each-query/</link>
					<comments>https://zxi.mytechroad.com/blog/priority-queue/leetcode-1851-minimum-interval-to-include-each-query/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 09 May 2021 06:05:19 +0000</pubDate>
				<category><![CDATA[Priority Queue]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[priority queue]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8439</guid>

					<description><![CDATA[You are given a 2D integer array&#160;intervals, where&#160;intervals[i] = [lefti, righti]&#160;describes the&#160;ith&#160;interval starting at&#160;lefti&#160;and ending at&#160;righti&#160;(inclusive). The&#160;size&#160;of an interval is defined as the number of&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You are given a 2D integer array&nbsp;<code>intervals</code>, where&nbsp;<code>intervals[i] = [left<sub>i</sub>, right<sub>i</sub>]</code>&nbsp;describes the&nbsp;<code>i<sup>th</sup></code>&nbsp;interval starting at&nbsp;<code>left<sub>i</sub></code>&nbsp;and ending at&nbsp;<code>right<sub>i</sub></code>&nbsp;<strong>(inclusive)</strong>. The&nbsp;<strong>size</strong>&nbsp;of an interval is defined as the number of integers it contains, or more formally&nbsp;<code>right<sub>i</sub>&nbsp;- left<sub>i</sub>&nbsp;+ 1</code>.</p>



<p>You are also given an integer array&nbsp;<code>queries</code>. The answer to the&nbsp;<code>j<sup>th</sup></code>&nbsp;query is the&nbsp;<strong>size of the smallest interval</strong>&nbsp;<code>i</code>&nbsp;such that&nbsp;<code>left<sub>i</sub>&nbsp;&lt;= queries[j] &lt;= right<sub>i</sub></code>. If no such interval exists, the answer is&nbsp;<code>-1</code>.</p>



<p>Return&nbsp;<em>an array containing the answers to the queries</em>.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> intervals = [[1,4],[2,4],[3,6],[4,4]], queries = [2,3,4,5]
<strong>Output:</strong> [3,3,1,4]
<strong>Explanation:</strong> The queries are processed as follows:
- Query = 2: The interval [2,4] is the smallest interval containing 2. The answer is 4 - 2 + 1 = 3.
- Query = 3: The interval [2,4] is the smallest interval containing 3. The answer is 4 - 2 + 1 = 3.
- Query = 4: The interval [4,4] is the smallest interval containing 4. The answer is 4 - 4 + 1 = 1.
- Query = 5: The interval [3,6] is the smallest interval containing 5. The answer is 6 - 3 + 1 = 4.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> intervals = [[2,3],[2,5],[1,8],[20,25]], queries = [2,19,5,22]
<strong>Output:</strong> [2,-1,4,6]
<strong>Explanation:</strong> The queries are processed as follows:
- Query = 2: The interval [2,3] is the smallest interval containing 2. The answer is 3 - 2 + 1 = 2.
- Query = 19: None of the intervals contain 19. The answer is -1.
- Query = 5: The interval [2,5] is the smallest interval containing 5. The answer is 5 - 2 + 1 = 4.
- Query = 22: The interval [20,25] is the smallest interval containing 22. The answer is 25 - 20 + 1 = 6.
</pre>



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



<ul class="wp-block-list"><li><code>1 &lt;= intervals.length &lt;= 10<sup>5</sup></code></li><li><code>1 &lt;= queries.length &lt;= 10<sup>5</sup></code></li><li><code>intervals[i].length == 2</code></li><li><code>1 &lt;= left<sub>i</sub>&nbsp;&lt;= right<sub>i</sub>&nbsp;&lt;= 10<sup>7</sup></code></li><li><code>1 &lt;= queries[j] &lt;= 10<sup>7</sup></code></li></ul>



<h2 class="wp-block-heading"><strong>Solution: Offline Processing</strong> <strong>+ Priority Queue</strong></h2>



<p>Similar to <a href="https://zxi.mytechroad.com/blog/algorithms/binary-search/leetcode-1847-closest-room/" data-type="post" data-id="8419">花花酱 LeetCode 1847. Closest Room</a></p>



<p>Sort intervals by right in descending order, sort queries in descending. Add valid intervals into the priority queue (or treeset) ordered by size in ascending order. Erase invalid ones. The first one (if any) will be the one with the smallest size that contains the current query.</p>



<p>Time complexity: O(nlogn + mlogm + mlogn)<br>Space complexity: O(m + n)</p>



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  vector&lt;int&gt; minInterval(vector&lt;vector&lt;int&gt;&gt;&amp; intervals, vector&lt;int&gt;&amp; queries) {
    const int n = intervals.size();
    const int m = queries.size();    
    sort(begin(intervals), end(intervals), [](const auto&amp; a, const auto&amp; b){
      return a[1] &gt; b[1];
    });
    vector&lt;pair&lt;int, int&gt;&gt; qs(m); // {query, i}
    for (int i = 0; i &lt; m; ++i)
      qs[i] = {queries[i], i};
    sort(rbegin(qs), rend(qs));

    vector&lt;int&gt; ans(m);
    int j = 0;
    priority_queue&lt;pair&lt;int, int&gt;&gt; pq; // {-size, left}
    for (const auto&amp; [query, i] : qs) {
      while (j &lt; n &amp;&amp; intervals[j][1] &gt;= query) {
        pq.emplace(-(intervals[j][1] - intervals[j][0] + 1),
                   intervals[j][0]);
        ++j;
      }
      while (!pq.empty() &amp;&amp; pq.top().second &gt; query) 
        pq.pop();      
      ans[i] = pq.empty() ? -1 : -pq.top().first;         
    }
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/priority-queue/leetcode-1851-minimum-interval-to-include-each-query/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1834. Single-Threaded CPU</title>
		<link>https://zxi.mytechroad.com/blog/simulation/leetcode-1834-single-threaded-cpu/</link>
					<comments>https://zxi.mytechroad.com/blog/simulation/leetcode-1834-single-threaded-cpu/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 18 Apr 2021 17:17:53 +0000</pubDate>
				<category><![CDATA[Simulation]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[min heap]]></category>
		<category><![CDATA[priority queue]]></category>
		<category><![CDATA[simulation]]></category>
		<category><![CDATA[sort]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8376</guid>

					<description><![CDATA[You are given&#160;n​​​​​​ tasks labeled from&#160;0&#160;to&#160;n - 1&#160;represented by a 2D integer array&#160;tasks, where&#160;tasks[i] = [enqueueTimei, processingTimei]&#160;means that the&#160;i​​​​​​th​​​​ task will be available to process&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You are given&nbsp;<code>n</code>​​​​​​ tasks labeled from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>n - 1</code>&nbsp;represented by a 2D integer array&nbsp;<code>tasks</code>, where&nbsp;<code>tasks[i] = [enqueueTime<sub>i</sub>, processingTime<sub>i</sub>]</code>&nbsp;means that the&nbsp;<code>i<sup>​​​​​​th</sup></code>​​​​ task will be available to process at&nbsp;<code>enqueueTime<sub>i</sub></code>&nbsp;and will take&nbsp;<code>processingTime<sub>i</sub></code>to finish processing.</p>



<p>You have a single-threaded CPU that can process&nbsp;<strong>at most one</strong>&nbsp;task at a time and will act in the following way:</p>



<ul class="wp-block-list"><li>If the CPU is idle and there are no available tasks to process, the CPU remains idle.</li><li>If the CPU is idle and there are available tasks, the CPU will choose the one with the&nbsp;<strong>shortest processing time</strong>. If multiple tasks have the same shortest processing time, it will choose the task with the smallest index.</li><li>Once a task is started, the CPU will&nbsp;<strong>process the entire task</strong>&nbsp;without stopping.</li><li>The CPU can finish a task then start a new one instantly.</li></ul>



<p>Return&nbsp;<em>the order in which the CPU will process the tasks.</em></p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> tasks = [[1,2],[2,4],[3,2],[4,1]]
<strong>Output:</strong> [0,2,3,1]
<strong>Explanation: </strong>The events go as follows: 
- At time = 1, task 0 is available to process. Available tasks = {0}.
- Also at time = 1, the idle CPU starts processing task 0. Available tasks = {}.
- At time = 2, task 1 is available to process. Available tasks = {1}.
- At time = 3, task 2 is available to process. Available tasks = {1, 2}.
- Also at time = 3, the CPU finishes task 0 and starts processing task 2 as it is the shortest. Available tasks = {1}.
- At time = 4, task 3 is available to process. Available tasks = {1, 3}.
- At time = 5, the CPU finishes task 2 and starts processing task 3 as it is the shortest. Available tasks = {1}.
- At time = 6, the CPU finishes task 3 and starts processing task 1. Available tasks = {}.
- At time = 10, the CPU finishes task 1 and becomes idle.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> tasks = [[7,10],[7,12],[7,5],[7,4],[7,2]]
<strong>Output:</strong> [4,3,2,0,1]
<strong>Explanation</strong><strong>: </strong>The events go as follows:
- At time = 7, all the tasks become available. Available tasks = {0,1,2,3,4}.
- Also at time = 7, the idle CPU starts processing task 4. Available tasks = {0,1,2,3}.
- At time = 9, the CPU finishes task 4 and starts processing task 3. Available tasks = {0,1,2}.
- At time = 13, the CPU finishes task 3 and starts processing task 2. Available tasks = {0,1}.
- At time = 18, the CPU finishes task 2 and starts processing task 0. Available tasks = {1}.
- At time = 28, the CPU finishes task 0 and starts processing task 1. Available tasks = {}.
- At time = 40, the CPU finishes task 1 and becomes idle.
</pre>



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



<ul class="wp-block-list"><li><code>tasks.length == n</code></li><li><code>1 &lt;= n &lt;= 10<sup>5</sup></code></li><li><code>1 &lt;= enqueueTime<sub>i</sub>, processingTime<sub>i</sub>&nbsp;&lt;= 10<sup>9</sup></code></li></ul>



<h2 class="wp-block-heading"><strong>Solution: Simulation w/ Sort + PQ</strong></h2>



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  vector&lt;int&gt; getOrder(vector&lt;vector&lt;int&gt;&gt;&amp; tasks) {
    const int n = tasks.size();
    for (int i = 0; i &lt; n; ++i)
      tasks[i].push_back(i);
    sort(begin(tasks), end(tasks)); // sort by enqueue_time;    
    
    vector&lt;int&gt; ans;
    priority_queue&lt;pair&lt;int, int&gt;&gt; q; // {-processing_time, -index}
    int i = 0;
    long t = 0;    
    while (ans.size() != n) {
      // Advance to next enqueue time if q is empty.
      if (i &lt; n &amp;&amp; q.empty() &amp;&amp; tasks[i][0] &gt; t)
        t = tasks[i][0];
      // Enqueue all available tasks.
      while (i &lt; n &amp;&amp; tasks[i][0] &lt;= t) {
        q.emplace(-tasks[i][1], -tasks[i][2]);
        ++i;
      }
      // Extra the top one.
      t -= q.top().first;
      ans.push_back(-q.top().second);
      q.pop();      
    }
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/simulation/leetcode-1834-single-threaded-cpu/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>LeetCode 1801. Number of Orders in the Backlog</title>
		<link>https://zxi.mytechroad.com/blog/priority-queue/leetcode-1801-number-of-orders-in-the-backlog/</link>
					<comments>https://zxi.mytechroad.com/blog/priority-queue/leetcode-1801-number-of-orders-in-the-backlog/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 22 Mar 2021 06:08:26 +0000</pubDate>
				<category><![CDATA[Priority Queue]]></category>
		<category><![CDATA[heap]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[priority queue]]></category>
		<category><![CDATA[treemap]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8266</guid>

					<description><![CDATA[You are given a 2D integer array&#160;orders, where each&#160;orders[i] = [pricei, amounti, orderTypei]&#160;denotes that&#160;amountiorders have been placed of type&#160;orderTypei&#160;at the price&#160;pricei. The&#160;orderTypei&#160;is: 0&#160;if it is&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You are given a 2D integer array&nbsp;<code>orders</code>, where each&nbsp;<code>orders[i] = [price<sub>i</sub>, amount<sub>i</sub>, orderType<sub>i</sub>]</code>&nbsp;denotes that&nbsp;<code>amount<sub>i</sub></code>orders have been placed of type&nbsp;<code>orderType<sub>i</sub></code>&nbsp;at the price&nbsp;<code>price<sub>i</sub></code>. The&nbsp;<code>orderType<sub>i</sub></code>&nbsp;is:</p>



<ul class="wp-block-list"><li><code>0</code>&nbsp;if it is a batch of&nbsp;<code>buy</code>&nbsp;orders, or</li><li><code>1</code>&nbsp;if it is a batch of&nbsp;<code>sell</code>&nbsp;orders.</li></ul>



<p>Note that&nbsp;<code>orders[i]</code>&nbsp;represents a batch of&nbsp;<code>amount<sub>i</sub></code>&nbsp;independent orders with the same price and order type. All orders represented by&nbsp;<code>orders[i]</code>&nbsp;will be placed before all orders represented by&nbsp;<code>orders[i+1]</code>&nbsp;for all valid&nbsp;<code>i</code>.</p>



<p>There is a&nbsp;<strong>backlog</strong>&nbsp;that consists of orders that have not been executed. The backlog is initially empty. When an order is placed, the following happens:</p>



<ul class="wp-block-list"><li>If the order is a&nbsp;<code>buy</code>&nbsp;order, you look at the&nbsp;<code>sell</code>&nbsp;order with the&nbsp;<strong>smallest</strong>&nbsp;price in the backlog. If that&nbsp;<code>sell</code>&nbsp;order&#8217;s price is&nbsp;<strong>smaller than or equal to</strong>&nbsp;the current&nbsp;<code>buy</code>&nbsp;order&#8217;s price, they will match and be executed, and that&nbsp;<code>sell</code>&nbsp;order will be removed from the backlog. Else, the&nbsp;<code>buy</code>&nbsp;order is added to the backlog.</li><li>Vice versa, if the order is a&nbsp;<code>sell</code>&nbsp;order, you look at the&nbsp;<code>buy</code>&nbsp;order with the&nbsp;<strong>largest</strong>&nbsp;price in the backlog. If that&nbsp;<code>buy</code>&nbsp;order&#8217;s price is&nbsp;<strong>larger than or equal to</strong>&nbsp;the current&nbsp;<code>sell</code>&nbsp;order&#8217;s price, they will match and be executed, and that&nbsp;<code>buy</code>&nbsp;order will be removed from the backlog. Else, the&nbsp;<code>sell</code>&nbsp;order is added to the backlog.</li></ul>



<p>Return&nbsp;<em>the total&nbsp;<strong>amount</strong>&nbsp;of orders in the backlog after placing all the orders from the input</em>. Since this number can be large, return it&nbsp;<strong>modulo</strong>&nbsp;<code>10<sup>9</sup>&nbsp;+ 7</code>.</p>



<p><strong>Example 1:</strong><img decoding="async" alt="" src="https://assets.leetcode.com/uploads/2021/03/11/ex1.png"></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> orders = [[10,5,0],[15,2,1],[25,1,1],[30,4,0]]
<strong>Output:</strong> 6
<strong>Explanation:</strong> Here is what happens with the orders:
- 5 orders of type buy with price 10 are placed. There are no sell orders, so the 5 orders are added to the backlog.
- 2 orders of type sell with price 15 are placed. There are no buy orders with prices larger than or equal to 15, so the 2 orders are added to the backlog.
- 1 order of type sell with price 25 is placed. There are no buy orders with prices larger than or equal to 25 in the backlog, so this order is added to the backlog.
- 4 orders of type buy with price 30 are placed. The first 2 orders are matched with the 2 sell orders of the least price, which is 15 and these 2 sell orders are removed from the backlog. The 3<sup>rd</sup> order is matched with the sell order of the least price, which is 25 and this sell order is removed from the backlog. Then, there are no more sell orders in the backlog, so the 4<sup>th</sup> order is added to the backlog.
Finally, the backlog has 5 buy orders with price 10, and 1 buy order with price 30. So the total number of orders in the backlog is 6.
</pre>



<p><strong>Example 2:</strong><img decoding="async" alt="" src="https://assets.leetcode.com/uploads/2021/03/11/ex2.png"></p>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> orders = [[7,1000000000,1],[15,3,0],[5,999999995,0],[5,1,1]]
<strong>Output:</strong> 999999984
<strong>Explanation:</strong> Here is what happens with the orders:
- 10<sup>9</sup> orders of type sell with price 7 are placed. There are no buy orders, so the 10<sup>9</sup> orders are added to the backlog.
- 3 orders of type buy with price 15 are placed. They are matched with the 3 sell orders with the least price which is 7, and those 3 sell orders are removed from the backlog.
- 999999995 orders of type buy with price 5 are placed. The least price of a sell order is 7, so the 999999995 orders are added to the backlog.
- 1 order of type sell with price 5 is placed. It is matched with the buy order of the highest price, which is 5, and that buy order is removed from the backlog.
Finally, the backlog has (1000000000-3) sell orders with price 7, and (999999995-1) buy orders with price 5. So the total number of orders = 1999999991, which is equal to 999999984 % (10<sup>9</sup> + 7).
</pre>



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



<ul class="wp-block-list"><li><code>1 &lt;= orders.length &lt;= 10<sup>5</sup></code></li><li><code>orders[i].length == 3</code></li><li><code>1 &lt;= price<sub>i</sub>, amount<sub>i</sub>&nbsp;&lt;= 10<sup>9</sup></code></li><li><code>orderType<sub>i</sub></code>&nbsp;is either&nbsp;<code>0</code>&nbsp;or&nbsp;<code>1</code>.</li></ul>



<h2 class="wp-block-heading"><strong>Solution: Treemap / PriorityQueue / Heap</strong></h2>



<p>buy backlog: max heap<br>sell backlog: min heap<br>Trade happens between the tops of two queues.</p>



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  int getNumberOfBacklogOrders(vector&lt;vector&lt;int&gt;&gt;&amp; orders) {  
    constexpr int kMod = 1e9 + 7;
    map&lt;int64_t, int64_t&gt; buys;
    map&lt;int64_t, int64_t&gt; sells;
    for (const auto&amp; order : orders) {      
      auto&amp; m = order[2] == 0 ? buys : sells;
      m[order[0]] += order[1];
      while (buys.size() &amp;&amp; sells.size()) {
        auto b = rbegin(buys);
        auto s = begin(sells);
        if (b-&gt;first &lt; s-&gt;first) break;
        const int k = min(b-&gt;second, s-&gt;second);
        if (!(b-&gt;second -= k)) buys.erase((++b).base());
        if (!(s-&gt;second -= k)) sells.erase(s);
      }
    }
    int64_t ans = 0;
    for (const auto&amp; [p, c] : buys) ans += c;
    for (const auto&amp; [p, c] : sells) ans += c;    
    return ans % kMod;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/priority-queue/leetcode-1801-number-of-orders-in-the-backlog/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1792. Maximum Average Pass Ratio</title>
		<link>https://zxi.mytechroad.com/blog/priority-queue/leetcode-1792-maximum-average-pass-ratio/</link>
					<comments>https://zxi.mytechroad.com/blog/priority-queue/leetcode-1792-maximum-average-pass-ratio/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 14 Mar 2021 06:49:53 +0000</pubDate>
				<category><![CDATA[Priority Queue]]></category>
		<category><![CDATA[greedy]]></category>
		<category><![CDATA[heap]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[priority queue]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8238</guid>

					<description><![CDATA[There is a school that has classes of students and each class will be having a final exam. You are given a 2D integer array&#160;classes,&#8230;]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-4-3 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="花花酱 LeetCode 1792. Maximum Average Pass Ratio - 刷题找工作 EP389" width="500" height="281" src="https://www.youtube.com/embed/wZMZemdsi90?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<p>There is a school that has classes of students and each class will be having a final exam. You are given a 2D integer array&nbsp;<code>classes</code>, where&nbsp;<code>classes[i] = [pass<sub>i</sub>, total<sub>i</sub>]</code>. You know beforehand that in the&nbsp;<code>i<sup>th</sup></code>&nbsp;class, there are&nbsp;<code>total<sub>i</sub></code>&nbsp;total students, but only&nbsp;<code>pass<sub>i</sub></code>&nbsp;number of students will pass the exam.</p>



<p>You are also given an integer&nbsp;<code>extraStudents</code>. There are another&nbsp;<code>extraStudents</code>&nbsp;brilliant students that are&nbsp;<strong>guaranteed</strong>&nbsp;to pass the exam of any class they are assigned to. You want to assign each of the&nbsp;<code>extraStudents</code>&nbsp;students to a class in a way that&nbsp;<strong>maximizes</strong>&nbsp;the&nbsp;<strong>average</strong>&nbsp;pass ratio across&nbsp;<strong>all</strong>&nbsp;the classes.</p>



<p>The&nbsp;<strong>pass ratio</strong>&nbsp;of a class is equal to the number of students of the class that will pass the exam divided by the total number of students of the class. The&nbsp;<strong>average pass ratio</strong>&nbsp;is the sum of pass ratios of all the classes divided by the number of the classes.</p>



<p>Return&nbsp;<em>the&nbsp;<strong>maximum</strong>&nbsp;possible average pass ratio after assigning the&nbsp;</em><code>extraStudents</code><em>&nbsp;students.&nbsp;</em>Answers within&nbsp;<code>10<sup>-5</sup></code>&nbsp;of the actual answer will be accepted.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> classes = [[1,2],[3,5],[2,2]], <code>extraStudents</code> = 2
<strong>Output:</strong> 0.78333
<strong>Explanation:</strong> You can assign the two extra students to the first class. The average pass ratio will be equal to (3/4 + 3/5 + 2/2) / 3 = 0.78333.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> classes = [[2,4],[3,9],[4,5],[2,10]], <code>extraStudents</code> = 4
<strong>Output:</strong> 0.53485
</pre>



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



<ul class="wp-block-list"><li><code>1 &lt;= classes.length &lt;= 10<sup>5</sup></code></li><li><code>classes[i].length == 2</code></li><li><code>1 &lt;= pass<sub>i</sub>&nbsp;&lt;= total<sub>i</sub>&nbsp;&lt;= 10<sup>5</sup></code></li><li><code>1 &lt;= extraStudents &lt;= 10<sup>5</sup></code></li></ul>



<h2 class="wp-block-heading"><strong>Solution: Greedy + Heap</strong></h2>



<figure class="wp-block-image size-large"><a href="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/03/1792-ep389-1.png"><img fetchpriority="high" decoding="async" width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/03/1792-ep389-1.png" alt="" class="wp-image-8241" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/03/1792-ep389-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2021/03/1792-ep389-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2021/03/1792-ep389-1-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></figure>



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



<p>Sort by the ratio increase potential (p + 1) / (t + 1) &#8211; p / t.</p>



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  double maxAverageRatio(vector&lt;vector&lt;int&gt;&gt;&amp; classes, int extraStudents) {
    const int n = classes.size();
    auto ratio = [&amp;](int i, int delta = 0) {
      return static_cast&lt;double&gt;(classes[i][0] + delta) / 
        (classes[i][1] + delta);
    };
    priority_queue&lt;pair&lt;double, int&gt;&gt; q;
    for (int i = 0; i &lt; n; ++i)
      q.emplace(ratio(i, 1) - ratio(i), i);
    while (extraStudents--) {
      const auto [r, i] = q.top(); q.pop();      
      ++classes[i][0];
      ++classes[i][1];
      q.emplace(ratio(i, 1) - ratio(i), i);
    }
    double total_ratio = 0;
    for (int i = 0; i &lt; n; ++i)
      total_ratio += ratio(i);
    return total_ratio / n;
  }
};</pre>

</div><h2 class="tabtitle">Python3</h2>
<div class="tabcontent">

<pre class="urvanov-syntax-highlighter-plain-tag"># Author: Huahua
class Solution:
  def maxAverageRatio(self, classes: List[List[int]], extraStudents: int) -&gt; float:
    def ratio(i, delta=0):
      return (classes[i][0] + delta) / (classes[i][1] + delta)
    q = []
    for i, c in enumerate(classes):
      heapq.heappush(q, (-(ratio(i, 1) - ratio(i)), i))
    for _ in range(extraStudents):
      _, i = heapq.heappop(q)
      classes[i][0] += 1
      classes[i][1] += 1
      heapq.heappush(q, (-(ratio(i, 1) - ratio(i)), i))
    return mean(ratio(i) for i, _ in enumerate(classes))</pre>
</div></div>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/priority-queue/leetcode-1792-maximum-average-pass-ratio/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1705. Maximum Number of Eaten Apples</title>
		<link>https://zxi.mytechroad.com/blog/priority-queue/leetcode-1705-maximum-number-of-eaten-apples/</link>
					<comments>https://zxi.mytechroad.com/blog/priority-queue/leetcode-1705-maximum-number-of-eaten-apples/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 27 Dec 2020 09:17:12 +0000</pubDate>
				<category><![CDATA[Priority Queue]]></category>
		<category><![CDATA[heap]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[priority queue]]></category>
		<category><![CDATA[sorting]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7861</guid>

					<description><![CDATA[There is a special kind of apple tree that grows apples every day for&#160;n&#160;days. On the&#160;ith&#160;day, the tree grows&#160;apples[i]&#160;apples that will rot after&#160;days[i]&#160;days, that is&#8230;]]></description>
										<content:encoded><![CDATA[
<p>There is a special kind of apple tree that grows apples every day for&nbsp;<code>n</code>&nbsp;days. On the&nbsp;<code>i<sup>th</sup></code>&nbsp;day, the tree grows&nbsp;<code>apples[i]</code>&nbsp;apples that will rot after&nbsp;<code>days[i]</code>&nbsp;days, that is on day&nbsp;<code>i + days[i]</code>&nbsp;the apples will be rotten and cannot be eaten. On some days, the apple tree does not grow any apples, which are denoted by&nbsp;<code>apples[i] == 0</code>&nbsp;and&nbsp;<code>days[i] == 0</code>.</p>



<p>You decided to eat&nbsp;<strong>at most</strong>&nbsp;one apple a day (to keep the doctors away). Note that you can keep eating after the first&nbsp;<code>n</code>&nbsp;days.</p>



<p>Given two integer arrays&nbsp;<code>days</code>&nbsp;and&nbsp;<code>apples</code>&nbsp;of length&nbsp;<code>n</code>, return&nbsp;<em>the maximum number of apples you can eat.</em></p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> apples = [1,2,3,5,2], days = [3,2,1,4,2]
<strong>Output:</strong> 7
<strong>Explanation:</strong> You can eat 7 apples:
- On the first day, you eat an apple that grew on the first day.
- On the second day, you eat an apple that grew on the second day.
- On the third day, you eat an apple that grew on the second day. After this day, the apples that grew on the third day rot.
- On the fourth to the seventh days, you eat apples that grew on the fourth day.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> apples = [3,0,0,0,0,2], days = [3,0,0,0,0,2]
<strong>Output:</strong> 5
<strong>Explanation:</strong> You can eat 5 apples:
- On the first to the third day you eat apples that grew on the first day.
- Do nothing on the fouth and fifth days.
- On the sixth and seventh days you eat apples that grew on the sixth day.
</pre>



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



<ul class="wp-block-list"><li><code>apples.length == n</code></li><li><code>days.length == n</code></li><li><code>1 &lt;= n &lt;= 2 * 10<sup>4</sup></code></li><li><code>0 &lt;= apples[i], days[i] &lt;= 2 * 10<sup>4</sup></code></li><li><code>days[i] = 0</code>&nbsp;if and only if&nbsp;<code>apples[i] = 0</code>.</li></ul>



<h2 class="wp-block-heading"><strong>Solution: PriorityQueue</strong></h2>



<p>Sort by rotten day in ascending order, only push onto the queue when that day has come (be able to grow apples).</p>



<p>Time complexity: O((n+ d)logn)<br>Space complexity: O(n)</p>



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  int eatenApples(vector&lt;int&gt;&amp; apples, vector&lt;int&gt;&amp; days) {
    const int n = apples.size();
    using P = pair&lt;int, int&gt;;    
    priority_queue&lt;P, vector&lt;P&gt;, greater&lt;P&gt;&gt; q; // {rotten_day, index}    
    int ans = 0;
    for (int d = 0; d &lt; n || !q.empty(); ++d) {
      if (d &lt; n &amp;&amp; apples[d]) q.emplace(d + days[d], d);
      while (!q.empty() 
             &amp;&amp; (q.top().first &lt;= d || apples[q.top().second] == 0)) q.pop();
      if (q.empty()) continue;
      --apples[q.top().second];      
      ++ans;
    }
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/priority-queue/leetcode-1705-maximum-number-of-eaten-apples/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1675. Minimize Deviation in Array</title>
		<link>https://zxi.mytechroad.com/blog/priority-queue/leetcode-1675-minimize-deviation-in-array/</link>
					<comments>https://zxi.mytechroad.com/blog/priority-queue/leetcode-1675-minimize-deviation-in-array/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 29 Nov 2020 21:54:59 +0000</pubDate>
				<category><![CDATA[Priority Queue]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[operation]]></category>
		<category><![CDATA[priority queue]]></category>
		<category><![CDATA[treeset]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7743</guid>

					<description><![CDATA[You are given an array&#160;nums&#160;of&#160;n&#160;positive integers. You can perform two types of operations on any element of the array any number of times: If the&#8230;]]></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 loading="lazy" title="花花酱 LeetCode 1675. Minimize Deviation in Array - 刷题找工作 EP372" width="500" height="281" src="https://www.youtube.com/embed/l_o4fp6BHYY?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<p>You are given an array&nbsp;<code>nums</code>&nbsp;of&nbsp;<code>n</code>&nbsp;positive integers.</p>



<p>You can perform two types of operations on any element of the array any number of times:</p>



<ul class="wp-block-list"><li>If the element is&nbsp;<strong>even</strong>,&nbsp;<strong>divide</strong>&nbsp;it by&nbsp;<code>2</code>.<ul><li>For example, if the array is&nbsp;<code>[1,2,3,4]</code>, then you can do this operation on the last element, and the array will be&nbsp;<code>[1,2,3,2].</code></li></ul></li><li>If the element is&nbsp;<strong>odd</strong>,&nbsp;<strong>multiply</strong>&nbsp;it by&nbsp;<code>2</code>.<ul><li>For example, if the array is&nbsp;<code>[1,2,3,4]</code>, then you can do this operation on the first element, and the array will be&nbsp;<code>[2,2,3,4].</code></li></ul></li></ul>



<p>The&nbsp;<strong>deviation</strong>&nbsp;of the array is the&nbsp;<strong>maximum difference</strong>&nbsp;between any two elements in the array.</p>



<p>Return&nbsp;<em>the&nbsp;<strong>minimum deviation</strong>&nbsp;the array can have after performing some number of operations.</em></p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [1,2,3,4]
<strong>Output:</strong> 1
<strong>Explanation:</strong> You can transform the array to [1,2,3,2], then to [2,2,3,2], then the deviation will be 3 - 2 = 1.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [4,1,5,20,3]
<strong>Output:</strong> 3
<strong>Explanation:</strong> You can transform the array after two operations to [4,2,5,5,3], then the deviation will be 5 - 2 = 3.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [2,10,8]
<strong>Output:</strong> 3
</pre>



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



<ul class="wp-block-list"><li><code>n == nums.length</code></li><li><code>2 &lt;= n &lt;= 10<sup>5</sup></code></li><li><code>1 &lt;= nums[i] &lt;= 10<sup>9</sup></code></li></ul>



<h2 class="wp-block-heading"><strong>Solution: Priority Queue</strong></h2>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/11/1675-ep372-1.png" alt="" class="wp-image-7755" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/11/1675-ep372-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/11/1675-ep372-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/11/1675-ep372-1-768x432.png 768w" sizes="auto, (max-width: 960px) 100vw, 960px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/11/1675-ep372-2.png" alt="" class="wp-image-7756" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/11/1675-ep372-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/11/1675-ep372-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/11/1675-ep372-2-768x432.png 768w" sizes="auto, (max-width: 960px) 100vw, 960px" /></figure>



<p>If we double an odd number it becomes an even number, then we can only divide it by two which gives us back the original number. So we can pre-double all the odd numbers and only do division in the following process. </p>



<p>We push all numbers including pre-doubled odd ones onto a priority queue, and track the difference between the largest and smallest number.</p>



<p>Each time, we pop the largest number out and divide it by two then put it back to the priority queue, until the largest number becomes odd. We can not discard it and divide any other smaller numbers by two will only increase the max difference, so we can stop here.</p>



<p>ex1: [3, 5, 8] =&gt; [6, 8, 10] (pre-double) =&gt; [5, 6, 8] =&gt; [4, 5, 6] =&gt; [3, 4, 5] max diff is 5 &#8211; 3 = 2<br>ex2: [4,1,5,20,3] =&gt; [2, 4, 6, 10, 20] (pre-double) =&gt; [2, 4, 6, 10] =&gt; [2, 4, 5, 6] =&gt; [2,3,4,5] max diff = 5-2 = 3</p>



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">class Solution {
public:
  int minimumDeviation(vector&lt;int&gt;&amp; nums) {
    set&lt;int&gt; s;
    for (int x : nums)
      s.insert(x &amp; 1 ? x * 2 : x);
    int ans = *rbegin(s) - *begin(s);
    while (*rbegin(s) % 2 == 0) {
      s.insert(*rbegin(s) / 2);
      s.erase(*rbegin(s));
      ans = min(ans, *rbegin(s) - *begin(s));
    }
    return ans;
  }
};</pre>

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

<pre class="urvanov-syntax-highlighter-plain-tag">class Solution {
public:
  int minimumDeviation(vector&lt;int&gt;&amp; nums) {
    priority_queue&lt;int&gt; q;    
    int lo = INT_MAX;
    for (int x : nums) {
      x = x &amp; 1 ? x * 2 : x;
      q.push(x);
      lo = min(lo, x);
    }
    int ans = q.top() - lo;
    while (q.top() % 2 == 0) {
      int x = q.top(); q.pop();
      q.push(x / 2);
      lo = min(lo, x / 2);
      ans = min(ans, q.top() - lo);
    }
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/priority-queue/leetcode-1675-minimize-deviation-in-array/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1439. Find the Kth Smallest Sum of a Matrix With Sorted Rows</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-1439-find-the-kth-smallest-sum-of-a-matrix-with-sorted-rows/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-1439-find-the-kth-smallest-sum-of-a-matrix-with-sorted-rows/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Wed, 06 May 2020 05:28:26 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[kth]]></category>
		<category><![CDATA[priority queue]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=6709</guid>

					<description><![CDATA[You are given an&#160;m&#160;* n&#160;matrix,&#160;mat, and an integer&#160;k,&#160;which&#160;has its rows sorted in non-decreasing&#160;order. You are allowed to choose exactly 1 element from each row to&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You are given an&nbsp;<code>m&nbsp;* n</code>&nbsp;matrix,&nbsp;<code>mat</code>, and an integer&nbsp;<code>k</code>,&nbsp;which&nbsp;has its rows sorted in non-decreasing&nbsp;order.</p>



<p>You are allowed to choose exactly 1 element from each row to form an array.&nbsp;Return the Kth&nbsp;<strong>smallest</strong>&nbsp;array sum among all possible arrays.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> mat = [[1,3,11],[2,4,6]], k = 5
<strong>Output:</strong> 7
<strong>Explanation: </strong>Choosing one element from each row, the first k smallest sum are:
[1,2], [1,4], [3,2], [3,4], [1,6]. Where the 5th sum is 7.  </pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> mat = [[1,3,11],[2,4,6]], k = 9
<strong>Output:</strong> 17
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> mat = [[1,10,10],[1,4,5],[2,3,6]], k = 7
<strong>Output:</strong> 9
<strong>Explanation:</strong> Choosing one element from each row, the first k smallest sum are:
[1,1,2], [1,1,3], [1,4,2], [1,4,3], [1,1,6], [1,5,2], [1,5,3]. Where the 7th sum is 9.  
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> mat = [[1,1,10],[2,2,9]], k = 7
<strong>Output:</strong> 12
</pre>



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



<ul class="wp-block-list"><li><code>m == mat.length</code></li><li><code>n == mat.length[i]</code></li><li><code>1 &lt;= m, n &lt;= 40</code></li><li><code>1 &lt;= k &lt;= min(200, n ^&nbsp;m)</code></li><li><code>1 &lt;= mat[i][j] &lt;= 5000</code></li><li><code>mat[i]</code>&nbsp;is a non decreasing array.</li></ul>



<h2 class="wp-block-heading"><strong>Solution 1: Priority Queue</strong></h2>



<p>Generate the arrays in order.</p>



<p>Each node is {sum, idx_0, idx_1, &#8230;, idx_m},</p>



<p>Start with {sum_0, 0, 0, &#8230;, 0}.</p>



<p>For expansion, pick one row and increase its index</p>



<p>Time complexity: O(k * m ^ 2* log k)<br>Space complexity: O(k)</p>



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  int kthSmallest(vector&lt;vector&lt;int&gt;&gt;&amp; mat, int k) {
    const int m = mat.size();
    const int n = mat[0].size();
    priority_queue&lt;vector&lt;int&gt;&gt; q;
    vector&lt;int&gt; node(m + 1); // {-sum, idx_0, idx_1, ..., idx_m}
    for (int i = 0; i &lt; m; ++i) node[0] -= mat[i][0];
    q.push(node);
    set&lt;vector&lt;int&gt;&gt; seen{{node}};
    while (!q.empty()) {
      const vector&lt;int&gt; cur = q.top(); q.pop();
      if (--k == 0) return -cur[0];  
      for (int i = 1; i &lt;= m; ++i) {
        if (cur[i] == n - 1) continue;
        vector&lt;int&gt; nxt(cur);
        ++nxt[i]; // increase i-th row's index.
        // Update sum.
        nxt[0] -= (mat[i - 1][nxt[i]] - mat[i - 1][nxt[i] - 1]);
        if (!seen.insert(nxt).second) continue;      
        q.push(move(nxt));
      }
    }
    return -1;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-1439-find-the-kth-smallest-sum-of-a-matrix-with-sorted-rows/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 630. Course Schedule III</title>
		<link>https://zxi.mytechroad.com/blog/greedy/leetcode-630-course-schedule-iii/</link>
					<comments>https://zxi.mytechroad.com/blog/greedy/leetcode-630-course-schedule-iii/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 11 May 2019 05:52:25 +0000</pubDate>
				<category><![CDATA[Greedy]]></category>
		<category><![CDATA[greedy]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[priority queue]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=5171</guid>

					<description><![CDATA[There are&#160;n&#160;different online courses numbered from&#160;1&#160;to&#160;n. Each course has some duration(course length)&#160;t&#160;and closed on&#160;dth&#160;day. A course should be taken&#160;continuouslyfor&#160;t&#160;days and must be finished before or&#8230;]]></description>
										<content:encoded><![CDATA[
<p>There are&nbsp;<code>n</code>&nbsp;different online courses numbered from&nbsp;<code>1</code>&nbsp;to&nbsp;<code>n</code>. Each course has some duration(course length)&nbsp;<code>t</code>&nbsp;and closed on&nbsp;<code>d<sub>th</sub></code>&nbsp;day. A course should be taken&nbsp;<strong>continuously</strong>for&nbsp;<code>t</code>&nbsp;days and must be finished before or on the&nbsp;<code>d<sub>th</sub></code>&nbsp;day. You will start at the&nbsp;<code>1<sub>st</sub></code>&nbsp;day.</p>



<p>Given&nbsp;<code>n</code>&nbsp;online courses represented by pairs&nbsp;<code>(t,d)</code>, your task is to find the maximal number of courses that can be taken.</p>



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



<pre class="wp-block-preformatted; crayon:false"><strong>Input:</strong> [[100, 200], [200, 1300], [1000, 1250], [2000, 3200]]
<strong>Output:</strong> 3
<strong>Explanation:</strong> 
There're totally 4 courses, but you can take 3 courses at most:
First, take the 1st course, it costs 100 days so you will finish it on the 100th day, and ready to take the next course on the 101st day.
Second, take the 3rd course, it costs 1000 days so you will finish it on the 1100th day, and ready to take the next course on the 1101st day. 
Third, take the 2nd course, it costs 200 days so you will finish it on the 1300th day. 
The 4th course cannot be taken now, since you will finish it on the 3300th day, which exceeds the closed date.
</pre>



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



<ol class="wp-block-list"><li>The integer 1 &lt;= d, t, n &lt;= 10,000.</li><li>You can&#8217;t take two courses simultaneously.</li></ol>



<h2 class="wp-block-heading"><strong>Solution: Priority queue</strong></h2>



<ol class="wp-block-list"><li>Sort courses by end date</li><li>Use a priority queue (Max-Heap) to store the course lengths or far</li><li>Swap with a longer course if we could not take the current one</li></ol>



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua, running time: 196 ms, 40.5 MB
class Solution {
public:
  int scheduleCourse(vector&lt;vector&lt;int&gt;&gt;&amp; courses) {
    sort(begin(courses), end(courses), [](const auto&amp; a, const auto&amp; b) {
      return a[1] &lt; b[1];
    });
    priority_queue&lt;int&gt; q;
    int d = 0;
    for (const auto&amp; c: courses) {
      if (d + c[0] &lt;= c[1]) {        
        d += c[0];
        q.push(c[0]);
      } else if (q.size() &amp;&amp; q.top() &gt; c[0]) {
        d += c[0] - q.top(); q.pop();
        q.push(c[0]);
      }
    }
    return q.size();
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/greedy/leetcode-630-course-schedule-iii/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 778. Swim in Rising Water</title>
		<link>https://zxi.mytechroad.com/blog/heap/leetcode-778-swim-in-rising-water/</link>
					<comments>https://zxi.mytechroad.com/blog/heap/leetcode-778-swim-in-rising-water/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Fri, 01 Feb 2019 04:46:57 +0000</pubDate>
				<category><![CDATA[Heap]]></category>
		<category><![CDATA[head]]></category>
		<category><![CDATA[path]]></category>
		<category><![CDATA[priority queue]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=4750</guid>

					<description><![CDATA[On an N x N&#160;grid, each square&#160;grid[i][j]&#160;represents the elevation at that point&#160;(i,j). Now rain starts to fall. At time&#160;t, the depth of the water everywhere&#8230;]]></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 loading="lazy" title="花花酱 LeetCode 778. Swim in Rising Water - 刷题找工作 EP244" width="500" height="375" src="https://www.youtube.com/embed/umdk98ynLSY?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



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



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



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



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



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

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



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



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

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



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



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



<h2 class="wp-block-heading"><strong>Solution 1: Dijkstra&#8217;s Algorithm</strong></h2>



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



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

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



<h2 class="wp-block-heading"><strong>Solution 2: Binary Search + BFS</strong></h2>



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua, running time: 8 ms
class Solution {
public:
  int swimInWater(vector&lt;vector&lt;int&gt;&gt;&amp; grid) {
    const int n = grid.size();
    auto hasPath = [&amp;grid, n](int t) {
      if (grid[0][0] &gt; t) return false;      
      queue&lt;int&gt; q;
      vector&lt;int&gt; seen(n * n);
      vector&lt;int&gt; dirs{1, 0, -1, 0, 1};
      q.push(0);
      
      while (!q.empty()) {
        const int x = q.front() % n;
        const int y = q.front() / n;
        q.pop();
        if (x == n - 1 &amp;&amp; y == n - 1) return true;
        for (int i = 0; i &lt; 4; ++i) {
          const int tx = x + dirs[i];
          const int ty = y + dirs[i + 1];
          if (tx &lt; 0 || ty &lt; 0 || tx &gt;= n || ty &gt;= n || grid[ty][tx] &gt; t) continue;
          const int key = ty * n + tx;
          if (seen[key]) continue;
          seen[key] = 1;
          q.push(key);
        }
      }
      return false;
    };
    int l = 0;
    int r = n * n;
    while (l &lt; r) {
      int m = l + (r - l) / 2;
      if (hasPath(m)) {
        r = m;
      } else {
        l = m + 1;
      }
    }
    return l;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/heap/leetcode-778-swim-in-rising-water/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 313. Super Ugly Number</title>
		<link>https://zxi.mytechroad.com/blog/math/leetcode-313-super-ugly-number/</link>
					<comments>https://zxi.mytechroad.com/blog/math/leetcode-313-super-ugly-number/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Thu, 03 Jan 2019 04:16:58 +0000</pubDate>
				<category><![CDATA[Math]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[prime]]></category>
		<category><![CDATA[priority queue]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=4590</guid>

					<description><![CDATA[Write a program to find the&#160;nth&#160;super ugly number. Super ugly numbers are positive numbers whose all prime factors are in the given prime list&#160;primes&#160;of size&#160;k.&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Write a program to find the&nbsp;<code>n<sup>th</sup></code>&nbsp;super ugly number.</p>



<p>Super ugly numbers are positive numbers whose all prime factors are in the given prime list&nbsp;<code>primes</code>&nbsp;of size&nbsp;<code>k</code>.</p>



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



<pre class="wp-block-preformatted crayon:false"><strong>Input:</strong> n = 12, <code>primes</code> = <code>[2,7,13,19]</code> <br><strong>Output:</strong> 32  <br><strong>Explanation: </strong><code>[1,2,4,7,8,13,14,16,19,26,28,32] </code>is the sequence of the first 12               super ugly numbers given <code>primes</code> = <code>[2,7,13,19]</code> of size 4.</pre>



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



<ul class="wp-block-list"><li><code>1</code>&nbsp;is a super ugly number for any given&nbsp;<code>primes</code>.</li><li>The given numbers in&nbsp;<code>primes</code>&nbsp;are in ascending order.</li><li>0 &lt;&nbsp;<code>k</code>&nbsp;≤ 100, 0 &lt;&nbsp;<code>n</code>&nbsp;≤ 10<sup>6</sup>, 0 &lt;&nbsp;<code>primes[i]</code>&nbsp;&lt; 1000.</li><li>The n<sup>th</sup>&nbsp;super ugly number is guaranteed to fit in a 32-bit signed integer.</li></ul>



<h2 class="wp-block-heading"><strong>Solution 1: Set</strong></h2>



<p>Maintain an ordered set of super ugly numbers, each time extract the smallest one, and multiply it with all primes and insert the new number into set.</p>



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua, running time: 484 ms
class Solution {
public:
  int nthSuperUglyNumber(int n, vector&lt;int&gt;&amp; primes) {
    if (n == 1) return 1;
    set&lt;int&gt; q{begin(primes), end(primes)};        
    for (int i = 0; i &lt; n - 2; ++i) {      
      auto it = begin(q);
      int t = *it;
      q.erase(it);
      for (int p : primes) {
        if (INT_MAX / t &lt; p) continue;        
        q.insert(p * t);
      }
      
    }
    return *begin(q);
  }
};</pre>
</div></div>



<h2 class="wp-block-heading"><strong>Solution 2: Priority Queue</strong></h2>



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua, 40 ms
struct Node {
  int num;
  int index;
  int prime;
  
  bool operator&gt;(const Node&amp; o) const {
    if (this-&gt;num == o.num) return this-&gt;index &gt; o.index;
    return this-&gt;num &gt; o.num;
  }
};

class Solution {
public:
  int nthSuperUglyNumber(int n, vector&lt;int&gt;&amp; primes) {
    if (n == 1) return 1;
    vector&lt;int&gt; nums(n, 1);
    priority_queue&lt;Node, vector&lt;Node&gt;, greater&lt;Node&gt;&gt; q;
    for (int p : primes)
      q.push({p, 1, p});
    for (int i = 1; i &lt; n; ++i) {
      nums[i] = q.top().num;
      while (nums[i] == q.top().num) {
        Node node = std::move(q.top()); q.pop();
        node.num = nums[node.index++] * node.prime;
        q.push(std::move(node));
      }
    }    
    return nums.back();
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/math/leetcode-313-super-ugly-number/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 895. Maximum Frequency Stack</title>
		<link>https://zxi.mytechroad.com/blog/desgin/leetcode-895-maximum-frequency-stack/</link>
					<comments>https://zxi.mytechroad.com/blog/desgin/leetcode-895-maximum-frequency-stack/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 26 Aug 2018 16:14:01 +0000</pubDate>
				<category><![CDATA[Desgin]]></category>
		<category><![CDATA[freq]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[priority queue]]></category>
		<category><![CDATA[stack]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=3705</guid>

					<description><![CDATA[Problem Implement FreqStack, a class which simulates the operation of a stack-like data structure. FreqStack has two functions: push(int x), which pushes an integer x onto the stack. pop(),&#8230;]]></description>
										<content:encoded><![CDATA[<p><iframe loading="lazy" title="花花酱 LeetCode 895. Maximum Frequency Stack - 刷题找工作 EP220" width="500" height="375" src="https://www.youtube.com/embed/IkrGghj6_fk?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></p>
<h1><strong>Problem</strong></h1>
<p>Implement <code>FreqStack</code>, a class which simulates the operation of a stack-like data structure.</p>
<p><code>FreqStack</code> has two functions:</p>
<ul>
<li><code>push(int x)</code>, which pushes an integer <code>x</code> onto the stack.</li>
<li><code>pop()</code>, which <strong>removes</strong> and returns the most frequent element in the stack.
<ul>
<li>If there is a tie for most frequent element, the element closest to the top of the stack is removed and returned.</li>
</ul>
</li>
</ul>
<p><strong>Example 1:</strong></p>
<pre class="crayon:false "><strong>Input: </strong>
<span id="example-input-1-1">["FreqStack","push","push","push","push","push","push","pop","pop","pop","pop"]</span>,
<span id="example-input-1-2">[[],[5],[7],[5],[7],[4],[5],[],[],[],[]]</span>
<strong>Output: </strong><span id="example-output-1">[null,null,null,null,null,null,null,5,7,5,4]</span>
<strong>Explanation</strong>:
After making six .push operations, the stack is [5,7,5,7,4,5] from bottom to top.  Then:

pop() -&gt; returns 5, as 5 is the most frequent.
The stack becomes [5,7,5,7,4].

pop() -&gt; returns 7, as 5 and 7 is the most frequent, but 7 is closest to the top.
The stack becomes [5,7,5,4].

pop() -&gt; returns 5.
The stack becomes [5,7,4].

pop() -&gt; returns 4.
The stack becomes [5,7].
</pre>
<p><strong>Note:</strong></p>
<ul>
<li>Calls to <code>FreqStack.push(int x)</code> will be such that <code>0 &lt;= x &lt;= 10^9</code>.</li>
<li>It is guaranteed that <code>FreqStack.pop()</code> won&#8217;t be called if the stack has zero elements.</li>
<li>The total number of <code>FreqStack.push</code> calls will not exceed <code>10000</code> in a single test case.</li>
<li>The total number of <code>FreqStack.pop</code> calls will not exceed <code>10000</code> in a single test case.</li>
<li>The total number of <code>FreqStack.push</code> and <code>FreqStack.pop</code> calls will not exceed <code>150000</code> across all test cases.</li>
</ul>
<p><ins class="adsbygoogle" style="display: block; text-align: center;" data-ad-layout="in-article" data-ad-format="fluid" data-ad-client="ca-pub-2404451723245401" data-ad-slot="7983117522"> </ins></p>
<h1><img loading="lazy" decoding="async" class="alignnone size-full wp-image-3710" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/08/895-ep220.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/08/895-ep220.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/08/895-ep220-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/08/895-ep220-768x432.png 768w" sizes="auto, (max-width: 960px) 100vw, 960px" /></h1>
<h1><strong>Solution 1: Buckets</strong></h1>
<p>We have n  stacks. The i-th stack has the of elements with freq i when pushed.</p>
<p>We keep tracking the freq of each element.</p>
<p>push(x): stacks[++freq(x)].push(x)  # inc x&#8217;s freq and push it onto freq-th stack</p>
<p>pop(): x = stacks[max_freq].pop(), &#8211;freq(x); # pop element x from the max_freq stack and dec it&#8217;s freq.</p>
<p>Time complexity: O(1) push / pop</p>
<p>Space complexity: O(n)</p>
<p><div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">
</p><pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
// Running time: 144 ms
class FreqStack {
public:
  FreqStack() {}

  void push(int x) {
    auto it = freq_.find(x);
    if (it == freq_.end())
      it = freq_.emplace(x, 0).first;    
    int freq = ++it-&gt;second;    
    if (stacks_.size() &lt; freq) stacks_.push_back({});
    stacks_[freq - 1].push(x);
  }

  int pop() {    
    int x = stacks_.back().top();    
    stacks_.back().pop();
    if (stacks_.back().empty())
      stacks_.pop_back();
    auto it = freq_.find(x);
    if (!(--it-&gt;second))
      freq_.erase(it);
    return x;
  }
private:  
  vector&lt;stack&lt;int&gt;&gt; stacks_;
  unordered_map&lt;int, int&gt; freq_;
};</pre><p></div></div></p>
<h1>Solution2: Priority Queue</h1>
<p>Use a max heap with key: (freq, seq), the max freq and closest to the top of stack element will be extracted first.</p>
<p>Time complexity: O(logn)</p>
<p>Space complexity: O(n)</p>
<p><div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">
</p><pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
// Running time: 132 ms
class FreqStack {
public:
  FreqStack() {}

  void push(int x) {    
    int key = (++f_[x] &lt;&lt; 16) | (++seq_);
    q_.emplace(key, x);
  }

  int pop() {
    int x = q_.top().second; q_.pop();    
    if (--f_[x] == 0)
      f_.erase(x);
    return x;
  }
private:
  int seq_ = 0;
  unordered_map&lt;int, int&gt; f_; // {x -&gt; freq}
  priority_queue&lt;pair&lt;int, int&gt;&gt; q_; // {freq | seq_, x}
};</pre><p></div></div></p>
<h1><strong>Related Problems</strong></h1>
<ul>
<li><a href="https://zxi.mytechroad.com/blog/hashtable/leetcode-460-lfu-cache/">花花酱 LeetCode 460. LFU Cache</a></li>
<li><a href="https://zxi.mytechroad.com/blog/hashtable/leetcode-146-lru-cache/">花花酱 LeetCode 146. LRU Cache O(1)</a></li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/desgin/leetcode-895-maximum-frequency-stack/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
