<?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>treeset &#8211; Huahua&#8217;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/tag/treeset/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog</link>
	<description></description>
	<lastBuildDate>Sun, 30 Mar 2025 15:17:54 +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>treeset &#8211; Huahua&#8217;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>花花酱 LeetCode 2349. Design a Number Container System</title>
		<link>https://zxi.mytechroad.com/blog/desgin/leetcode-2349-design-a-number-container-system/</link>
					<comments>https://zxi.mytechroad.com/blog/desgin/leetcode-2349-design-a-number-container-system/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 30 Mar 2025 15:16:49 +0000</pubDate>
				<category><![CDATA[Desgin]]></category>
		<category><![CDATA[hashtable]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[treeset]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=10244</guid>

					<description><![CDATA[两个hashtable，一个是index->number，另外一个是number -> {index}，使用treeset，自动排序。 时间复杂度：change O(logn)，find O(1)空间复杂度：O(n) [crayon-67ec269a96a12753106019/]]]></description>
										<content:encoded><![CDATA[
<p>两个hashtable，一个是index->number，另外一个是number -> {index}，使用treeset，自动排序。</p>



<p>时间复杂度：change O(logn)，find O(1)<br>空间复杂度：O(n)</p>



<pre class="urvanov-syntax-highlighter-plain-tag">class NumberContainers {
public:
  NumberContainers() {}
  
  void change(int index, int number) {
    if (m_.count(index)) {
      auto it = idx_.find(m_[index]);
      it-&gt;second.erase(index);
      if (it-&gt;second.empty())
        idx_.erase(it);
    }
    m_[index] = number;
    idx_[number].insert(index);
  }
  
  int find(int number) {
    auto it = idx_.find(number);
    if (it == end(idx_)) return -1;
    return *begin(it-&gt;second);
  }
private:
  unordered_map&lt;int, int&gt; m_; // index -&gt; num
  unordered_map&lt;int, set&lt;int&gt;&gt; idx_; // num -&gt; {index}
};</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/desgin/leetcode-2349-design-a-number-container-system/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2353. Design a Food Rating System</title>
		<link>https://zxi.mytechroad.com/blog/hashtable/leetcode-2353-design-a-food-rating-system/</link>
					<comments>https://zxi.mytechroad.com/blog/hashtable/leetcode-2353-design-a-food-rating-system/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 30 Mar 2025 00:38:41 +0000</pubDate>
				<category><![CDATA[Hashtable]]></category>
		<category><![CDATA[hashtable]]></category>
		<category><![CDATA[iterator]]></category>
		<category><![CDATA[orderedset]]></category>
		<category><![CDATA[treeset]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=10241</guid>

					<description><![CDATA[Hashtable + TreeSet / OrderedSet 用了三个Hashtable&#8230; 菜名 -> 菜系 菜系 -> Treemap 菜名 -> 所在Treemap中的迭代器 每个菜系用一个TreeSet来保存从高到低的菜色排名，查询的时候只要拿出第一个就好了。 修改的时候，拿出迭代器，删除原来的评分，再把新的评分加入（别忘了更新迭代器） 时间复杂度：构造O(nlogn)，修改O(logn)，查询O(1) 空间复杂度：O(n) [crayon-67ec269a971b9565060623/]]]></description>
										<content:encoded><![CDATA[
<p>Hashtable + TreeSet / OrderedSet</p>



<p>用了三个Hashtable&#8230;</p>



<ol class="wp-block-list"><li>菜名 -> 菜系</li><li>菜系 -> Treemap</li><li>菜名 -> 所在Treemap中的迭代器</li></ol>



<p>每个菜系用一个TreeSet来保存从高到低的菜色排名，查询的时候只要拿出第一个就好了。</p>



<p>修改的时候，拿出迭代器，删除原来的评分，再把新的评分加入（别忘了更新迭代器）</p>



<p>时间复杂度：构造O(nlogn)，修改O(logn)，查询O(1)</p>



<p>空间复杂度：O(n)</p>



<pre class="urvanov-syntax-highlighter-plain-tag">class FoodRatings {
public:
  FoodRatings(vector&lt;string&gt;&amp; foods, vector&lt;string&gt;&amp; cuisines, vector&lt;int&gt;&amp; ratings) {
    const int n = foods.size();
    for (int i = 0; i &lt; n; ++i) {
      n_[foods[i]] = cuisines[i];
      m_[foods[i]] = c_[cuisines[i]].emplace(-ratings[i], foods[i]).first;
    }
  }
  
  void changeRating(string food, int newRating) {
    const string&amp; cuisine = n_[food];
    c_[cuisine].erase(m_[food]);
    m_[food] = c_[cuisine].emplace(-newRating, food).first;
  }
  
  string highestRated(string cuisine) {
    return begin(c_[cuisine])-&gt;second;
  }
private:
  unordered_map&lt;string, set&lt;pair&lt;int, string&gt;&gt;&gt; c_; // cuisine -&gt; {{-rating, name}}
  unordered_map&lt;string, string&gt; n_; // food -&gt; cuisine  
  unordered_map&lt;string, set&lt;pair&lt;int, string&gt;&gt;::iterator&gt; m_; // food -&gt; set iterator
};

/**
 * Your FoodRatings object will be instantiated and called as such:
 * FoodRatings* obj = new FoodRatings(foods, cuisines, ratings);
 * obj-&gt;changeRating(food,newRating);
 * string param_2 = obj-&gt;highestRated(cuisine);
 */</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/hashtable/leetcode-2353-design-a-food-rating-system/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1912. Design Movie Rental System</title>
		<link>https://zxi.mytechroad.com/blog/data-structure/leetcode-1912-design-movie-rental-system/</link>
					<comments>https://zxi.mytechroad.com/blog/data-structure/leetcode-1912-design-movie-rental-system/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 01 Jan 2022 23:40:32 +0000</pubDate>
				<category><![CDATA[Data Structure]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[hashtable]]></category>
		<category><![CDATA[treeset]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9387</guid>

					<description><![CDATA[You have a movie renting company consisting of&#160;n&#160;shops. You want to implement a renting system that supports searching for, booking, and returning movies. The system&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You have a movie renting company consisting of&nbsp;<code>n</code>&nbsp;shops. You want to implement a renting system that supports searching for, booking, and returning movies. The system should also support generating a report of the currently rented movies.</p>



<p>Each movie is given as a 2D integer array&nbsp;<code>entries</code>&nbsp;where&nbsp;<code>entries[i] = [shop<sub>i</sub>, movie<sub>i</sub>, price<sub>i</sub>]</code>&nbsp;indicates that there is a copy of movie&nbsp;<code>movie<sub>i</sub></code>&nbsp;at shop&nbsp;<code>shop<sub>i</sub></code>&nbsp;with a rental price of&nbsp;<code>price<sub>i</sub></code>. Each shop carries&nbsp;<strong>at most one</strong>&nbsp;copy of a movie&nbsp;<code>movie<sub>i</sub></code>.</p>



<p>The system should support the following functions:</p>



<ul class="wp-block-list"><li><strong>Search</strong>: Finds the&nbsp;<strong>cheapest 5 shops</strong>&nbsp;that have an&nbsp;<strong>unrented copy</strong>&nbsp;of a given movie. The shops should be sorted by&nbsp;<strong>price</strong>&nbsp;in ascending order, and in case of a tie, the one with the&nbsp;<strong>smaller&nbsp;</strong><code>shop<sub>i</sub></code>&nbsp;should appear first. If there are less than 5 matching shops, then all of them should be returned. If no shop has an unrented copy, then an empty list should be returned.</li><li><strong>Rent</strong>: Rents an&nbsp;<strong>unrented copy</strong>&nbsp;of a given movie from a given shop.</li><li><strong>Drop</strong>: Drops off a&nbsp;<strong>previously rented copy</strong>&nbsp;of a given movie at a given shop.</li><li><strong>Report</strong>: Returns the&nbsp;<strong>cheapest 5 rented movies</strong>&nbsp;(possibly of the same movie ID) as a 2D list&nbsp;<code>res</code>&nbsp;where&nbsp;<code>res[j] = [shop<sub>j</sub>, movie<sub>j</sub>]</code>&nbsp;describes that the&nbsp;<code>j<sup>th</sup></code>&nbsp;cheapest rented movie&nbsp;<code>movie<sub>j</sub></code>&nbsp;was rented from the shop&nbsp;<code>shop<sub>j</sub></code>. The movies in&nbsp;<code>res</code>&nbsp;should be sorted by&nbsp;<strong>price&nbsp;</strong>in ascending order, and in case of a tie, the one with the&nbsp;<strong>smaller&nbsp;</strong><code>shop<sub>j</sub></code>&nbsp;should appear first, and if there is still tie, the one with the&nbsp;<strong>smaller&nbsp;</strong><code>movie<sub>j</sub></code>&nbsp;should appear first. If there are fewer than 5 rented movies, then all of them should be returned. If no movies are currently being rented, then an empty list should be returned.</li></ul>



<p>Implement the&nbsp;<code>MovieRentingSystem</code>&nbsp;class:</p>



<ul class="wp-block-list"><li><code>MovieRentingSystem(int n, int[][] entries)</code>&nbsp;Initializes the&nbsp;<code>MovieRentingSystem</code>&nbsp;object with&nbsp;<code>n</code>&nbsp;shops and the movies in&nbsp;<code>entries</code>.</li><li><code>List&lt;Integer&gt; search(int movie)</code>&nbsp;Returns a list of shops that have an&nbsp;<strong>unrented copy</strong>&nbsp;of the given&nbsp;<code>movie</code>&nbsp;as described above.</li><li><code>void rent(int shop, int movie)</code>&nbsp;Rents the given&nbsp;<code>movie</code>&nbsp;from the given&nbsp;<code>shop</code>.</li><li><code>void drop(int shop, int movie)</code>&nbsp;Drops off a previously rented&nbsp;<code>movie</code>&nbsp;at the given&nbsp;<code>shop</code>.</li><li><code>List&lt;List&lt;Integer&gt;&gt; report()</code>&nbsp;Returns a list of cheapest&nbsp;<strong>rented</strong>&nbsp;movies as described above.</li></ul>



<p><strong>Note:</strong>&nbsp;The test cases will be generated such that&nbsp;<code>rent</code>&nbsp;will only be called if the shop has an&nbsp;<strong>unrented</strong>&nbsp;copy of the movie, and&nbsp;<code>drop</code>&nbsp;will only be called if the shop had&nbsp;<strong>previously rented</strong>&nbsp;out the movie.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input</strong>
["MovieRentingSystem", "search", "rent", "rent", "report", "drop", "search"]
[[3, [[0, 1, 5], [0, 2, 6], [0, 3, 7], [1, 1, 4], [1, 2, 7], [2, 1, 5]]], [1], [0, 1], [1, 2], [], [1, 2], [2]]
<strong>Output</strong>
[null, [1, 0, 2], null, null, [[0, 1], [1, 2]], null, [0, 1]]

<strong>Explanation</strong>
MovieRentingSystem movieRentingSystem = new MovieRentingSystem(3, [[0, 1, 5], [0, 2, 6], [0, 3, 7], [1, 1, 4], [1, 2, 7], [2, 1, 5]]);
movieRentingSystem.search(1);  // return [1, 0, 2], Movies of ID 1 are unrented at shops 1, 0, and 2. Shop 1 is cheapest; shop 0 and 2 are the same price, so order by shop number.
movieRentingSystem.rent(0, 1); // Rent movie 1 from shop 0. Unrented movies at shop 0 are now [2,3].
movieRentingSystem.rent(1, 2); // Rent movie 2 from shop 1. Unrented movies at shop 1 are now [1].
movieRentingSystem.report();   // return [[0, 1], [1, 2]]. Movie 1 from shop 0 is cheapest, followed by movie 2 from shop 1.
movieRentingSystem.drop(1, 2); // Drop off movie 2 at shop 1. Unrented movies at shop 1 are now [1,2].
movieRentingSystem.search(2);  // return [0, 1]. Movies of ID 2 are unrented at shops 0 and 1. Shop 0 is cheapest, followed by shop 1.
</pre>



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



<ul class="wp-block-list"><li><code>1 &lt;= n &lt;= 3 * 10<sup>5</sup></code></li><li><code>1 &lt;= entries.length &lt;= 10<sup>5</sup></code></li><li><code>0 &lt;= shop<sub>i</sub>&nbsp;&lt; n</code></li><li><code>1 &lt;= movie<sub>i</sub>, price<sub>i</sub>&nbsp;&lt;= 10<sup>4</sup></code></li><li>Each shop carries&nbsp;<strong>at most one</strong>&nbsp;copy of a movie&nbsp;<code>movie<sub>i</sub></code>.</li><li>At most&nbsp;<code>10<sup>5</sup></code>&nbsp;calls&nbsp;<strong>in total</strong>&nbsp;will be made to&nbsp;<code>search</code>,&nbsp;<code>rent</code>,&nbsp;<code>drop</code>&nbsp;and&nbsp;<code>report</code>.</li></ul>



<h2 class="wp-block-heading"><strong>Solution: Hashtable + TreeSet</strong></h2>



<p>We need three containers:<br>1. <strong><em>movies</em></strong> tracks the {movie -&gt; price} of each shop. This is readonly to get the price of a movie for generating keys for treesets.<br>2. <strong><em>unrented</em></strong> tracks unrented movies keyed by movie id,  value is a treeset ordered by {price, shop}.<br>3. <strong><em>rented</em></strong> tracks rented movies, a treeset <meta charset="utf-8">ordered by {price, shop, movie}</p>



<p>Note: By using array&lt;int, 3&gt; we can unpack values like below:<br>array&lt;int, 3&gt; entries; // {price, shop, movie}<br>for (const auto [price, shop, moive] : entries)<br>  &#8230;</p>



<p>Time complexity: <br>Init: O(nlogn)<br>rent / drop: O(logn)<br>search / report: O(1)</p>



<p>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 MovieRentingSystem {
public:
  MovieRentingSystem(int n, vector&lt;vector&lt;int&gt;&gt;&amp; entries): movies(n) {
    for (const auto&amp; e : entries) {
      const int shop = e[0];
      const int movie = e[1];
      const int price = e[2];
      movies[shop].emplace(movie, price);
      unrented[movie].emplace(price, shop);
    }
  }

  vector&lt;int&gt; search(int movie) {
    vector&lt;int&gt; shops;
    for (const auto [price, shop] : unrented[movie]) {
      shops.push_back(shop);
      if (shops.size() == 5) break;
    }
    return shops;
  }

  void rent(int shop, int movie) {
    const int price = movies[shop][movie];
    unrented[movie].erase({price, shop});
    rented.insert({price, shop, movie});
  }

  void drop(int shop, int movie) {
    const int price = movies[shop][movie];
    rented.erase({price, shop, movie});
    unrented[movie].emplace(price, shop);
  }

  vector&lt;vector&lt;int&gt;&gt; report() {
    vector&lt;vector&lt;int&gt;&gt; ans;
    for (const auto&amp; [price, shop, movie] : rented) {
      ans.push_back({shop, movie});
      if (ans.size() == 5) break;
    }
    return ans;
  }
private:
  vector&lt;unordered_map&lt;int, int&gt;&gt; movies; // shop -&gt; {movie -&gt; price}
  unordered_map&lt;int, set&lt;pair&lt;int, int&gt;&gt;&gt; unrented; // movie -&gt; {price, shop}
  set&lt;array&lt;int, 3&gt;&gt; rented; // {price, shop, movie}
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/data-structure/leetcode-1912-design-movie-rental-system/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1942. The Number of the Smallest Unoccupied Chair</title>
		<link>https://zxi.mytechroad.com/blog/priority-queue/leetcode-1942-the-number-of-the-smallest-unoccupied-chair/</link>
					<comments>https://zxi.mytechroad.com/blog/priority-queue/leetcode-1942-the-number-of-the-smallest-unoccupied-chair/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Fri, 31 Dec 2021 13:50:08 +0000</pubDate>
				<category><![CDATA[Priority Queue]]></category>
		<category><![CDATA[events]]></category>
		<category><![CDATA[heap]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[sorting]]></category>
		<category><![CDATA[treeset]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9308</guid>

					<description><![CDATA[There is a party where&#160;n&#160;friends numbered from&#160;0&#160;to&#160;n - 1&#160;are attending. There is an&#160;infinite&#160;number of chairs in this party that are numbered from&#160;0&#160;to&#160;infinity. When a friend&#8230;]]></description>
										<content:encoded><![CDATA[
<p>There is a party where&nbsp;<code>n</code>&nbsp;friends numbered from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>n - 1</code>&nbsp;are attending. There is an&nbsp;<strong>infinite</strong>&nbsp;number of chairs in this party that are numbered from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>infinity</code>. When a friend arrives at the party, they sit on the unoccupied chair with the&nbsp;<strong>smallest number</strong>.</p>



<ul class="wp-block-list"><li>For example, if chairs&nbsp;<code>0</code>,&nbsp;<code>1</code>, and&nbsp;<code>5</code>&nbsp;are occupied when a friend comes, they will sit on chair number&nbsp;<code>2</code>.</li></ul>



<p>When a friend leaves the party, their chair becomes unoccupied at the moment they leave. If another friend arrives at that same moment, they can sit in that chair.</p>



<p>You are given a&nbsp;<strong>0-indexed</strong>&nbsp;2D integer array&nbsp;<code>times</code>&nbsp;where&nbsp;<code>times[i] = [arrival<sub>i</sub>, leaving<sub>i</sub>]</code>, indicating the arrival and leaving times of the&nbsp;<code>i<sup>th</sup></code>&nbsp;friend respectively, and an integer&nbsp;<code>targetFriend</code>. All arrival times are&nbsp;<strong>distinct</strong>.</p>



<p>Return<em>&nbsp;the&nbsp;<strong>chair number</strong>&nbsp;that the friend numbered&nbsp;</em><code>targetFriend</code><em>&nbsp;will sit on</em>.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> times = [[1,4],[2,3],[4,6]], targetFriend = 1
<strong>Output:</strong> 1
<strong>Explanation:</strong> 
- Friend 0 arrives at time 1 and sits on chair 0.
- Friend 1 arrives at time 2 and sits on chair 1.
- Friend 1 leaves at time 3 and chair 1 becomes empty.
- Friend 0 leaves at time 4 and chair 0 becomes empty.
- Friend 2 arrives at time 4 and sits on chair 0.
Since friend 1 sat on chair 1, we return 1.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> times = [[3,10],[1,5],[2,6]], targetFriend = 0
<strong>Output:</strong> 2
<strong>Explanation:</strong> 
- Friend 1 arrives at time 1 and sits on chair 0.
- Friend 2 arrives at time 2 and sits on chair 1.
- Friend 0 arrives at time 3 and sits on chair 2.
- Friend 1 leaves at time 5 and chair 0 becomes empty.
- Friend 2 leaves at time 6 and chair 1 becomes empty.
- Friend 0 leaves at time 10 and chair 2 becomes empty.
Since friend 0 sat on chair 2, we return 2.
</pre>



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



<ul class="wp-block-list"><li><code>n == times.length</code></li><li><code>2 &lt;= n &lt;= 10<sup>4</sup></code></li><li><code>times[i].length == 2</code></li><li><code>1 &lt;= arrival<sub>i</sub>&nbsp;&lt; leaving<sub>i</sub>&nbsp;&lt;= 10<sup>5</sup></code></li><li><code>0 &lt;= targetFriend &lt;= n - 1</code></li><li>Each&nbsp;<code>arrival<sub>i</sub></code>&nbsp;time is&nbsp;<strong>distinct</strong>.</li></ul>



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



<p>Use a treeset to track available chairs, sort events by time.<br>note: process leaving events first.</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 smallestChair(vector&lt;vector&lt;int&gt;&gt;&amp; times, int targetFriend) {
    const int n = times.size();
    vector&lt;pair&lt;int, int&gt;&gt; arrival(n);
    vector&lt;pair&lt;int, int&gt;&gt; leaving(n);
    for (int i = 0; i &lt; n; ++i) {
      arrival[i] = {times[i][0], i};
      leaving[i] = {times[i][1], i};
    }
    vector&lt;int&gt; pos(n);
    iota(begin(pos), end(pos), 0); // pos = [0, 1, ..., n -1]
    set&lt;int&gt; aval(begin(pos), end(pos));    
    sort(begin(arrival), end(arrival));
    sort(begin(leaving), end(leaving));
    for (int i = 0, j = 0; i &lt; n; ++i) {
      const auto [t, u] = arrival[i];
      while (j &lt; n &amp;&amp; leaving[j].first &lt;= t)        
        aval.insert(pos[leaving[j++].second]);        
      aval.erase(pos[u] = *begin(aval));      
      if (u == targetFriend) return pos[u];
    }
    return -1;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/priority-queue/leetcode-1942-the-number-of-the-smallest-unoccupied-chair/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2102. Sequentially Ordinal Rank Tracker</title>
		<link>https://zxi.mytechroad.com/blog/data-structure/leetcode-2102-sequentially-ordinal-rank-tracker/</link>
					<comments>https://zxi.mytechroad.com/blog/data-structure/leetcode-2102-sequentially-ordinal-rank-tracker/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 12 Dec 2021 22:07:45 +0000</pubDate>
				<category><![CDATA[Data Structure]]></category>
		<category><![CDATA[data structure]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[iterator]]></category>
		<category><![CDATA[set]]></category>
		<category><![CDATA[treeset]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9143</guid>

					<description><![CDATA[A scenic location is represented by its&#160;name&#160;and attractiveness&#160;score, where&#160;name&#160;is a&#160;unique&#160;string among all locations and&#160;score&#160;is an integer. Locations can be ranked from the best to the&#8230;]]></description>
										<content:encoded><![CDATA[
<p>A scenic location is represented by its&nbsp;<code>name</code>&nbsp;and attractiveness&nbsp;<code>score</code>, where&nbsp;<code>name</code>&nbsp;is a&nbsp;<strong>unique</strong>&nbsp;string among all locations and&nbsp;<code>score</code>&nbsp;is an integer. Locations can be ranked from the best to the worst. The&nbsp;<strong>higher</strong>&nbsp;the score, the better the location. If the scores of two locations are equal, then the location with the&nbsp;<strong>lexicographically smaller</strong>&nbsp;name is better.</p>



<p>You are building a system that tracks the ranking of locations with the system initially starting with no locations. It supports:</p>



<ul class="wp-block-list"><li><strong>Adding</strong>&nbsp;scenic locations,&nbsp;<strong>one at a time</strong>.</li><li><strong>Querying</strong>&nbsp;the&nbsp;<code>i<sup>th</sup></code>&nbsp;<strong>best</strong>&nbsp;location of&nbsp;<strong>all locations already added</strong>, where&nbsp;<code>i</code>&nbsp;is the number of times the system has been queried (including the current query).<ul><li>For example, when the system is queried for the&nbsp;<code>4<sup>th</sup></code>&nbsp;time, it returns the&nbsp;<code>4<sup>th</sup></code>&nbsp;best location of all locations already added.</li></ul></li></ul>



<p>Note that the test data are generated so that&nbsp;<strong>at any time</strong>, the number of queries&nbsp;<strong>does not exceed</strong>&nbsp;the number of locations added to the system.</p>



<p>Implement the&nbsp;<code>SORTracker</code>&nbsp;class:</p>



<ul class="wp-block-list"><li><code>SORTracker()</code>&nbsp;Initializes the tracker system.</li><li><code>void add(string name, int score)</code>&nbsp;Adds a scenic location with&nbsp;<code>name</code>&nbsp;and&nbsp;<code>score</code>&nbsp;to the system.</li><li><code>string get()</code>&nbsp;Queries and returns the&nbsp;<code>i<sup>th</sup></code>&nbsp;best location, where&nbsp;<code>i</code>&nbsp;is the number of times this method has been invoked (including this invocation).</li></ul>



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



<pre class="urvanov-syntax-highlighter-plain-tag">&lt;strong&gt;Input&lt;/strong&gt;
[&quot;SORTracker&quot;, &quot;add&quot;, &quot;add&quot;, &quot;get&quot;, &quot;add&quot;, &quot;get&quot;, &quot;add&quot;, &quot;get&quot;, &quot;add&quot;, &quot;get&quot;, &quot;add&quot;, &quot;get&quot;, &quot;get&quot;]
[[], [&quot;bradford&quot;, 2], [&quot;branford&quot;, 3], [], [&quot;alps&quot;, 2], [], [&quot;orland&quot;, 2], [], [&quot;orlando&quot;, 3], [], [&quot;alpine&quot;, 2], [], []]
&lt;strong&gt;Output&lt;/strong&gt;
[null, null, null, &quot;branford&quot;, null, &quot;alps&quot;, null, &quot;bradford&quot;, null, &quot;bradford&quot;, null, &quot;bradford&quot;, &quot;orland&quot;]
&lt;p&gt;&lt;strong&gt;Explanation&lt;/strong&gt; 
SORTracker tracker = new SORTracker(); // Initialize the tracker system.
tracker.add(&quot;bradford&quot;, 2);            // Add location with name=&quot;bradford&quot; and score=2 to the system.
tracker.add(&quot;branford&quot;, 3);            // Add location with name=&quot;branford&quot; and score=3 to the system.
tracker.get();                         // The sorted locations, from best to worst, are: branford, bradford. 
                                       // Note that branford precedes bradford due to its &lt;strong&gt;higher score&lt;/strong&gt; (3 &amp;gt; 2). 
                                       // This is the 1&lt;sup&gt;st&lt;/sup&gt; time get() is called, so return the best location: &quot;branford&quot;. 
tracker.add(&quot;alps&quot;, 2);                // Add location with name=&quot;alps&quot; and score=2 to the system.
tracker.get();                         // Sorted locations: branford, alps, bradford. 
                                       // Note that alps precedes bradford even though they have the same score (2). 
                                       // This is because &quot;alps&quot; is &lt;strong&gt;lexicographically smaller&lt;/strong&gt; than &quot;bradford&quot;. 
                                       // Return the 2&lt;sup&gt;nd&lt;/sup&gt; best location &quot;alps&quot;, as it is the 2&lt;sup&gt;nd&lt;/sup&gt; time get() is called.
tracker.add(&quot;orland&quot;, 2);              // Add location with name=&quot;orland&quot; and score=2 to the system.
tracker.get();                         // Sorted locations: branford, alps, bradford, orland. 
                                       // Return &quot;bradford&quot;, as it is the 3&lt;sup&gt;rd&lt;/sup&gt; time get() is called. 
tracker.add(&quot;orlando&quot;, 3);             // Add location with name=&quot;orlando&quot; and score=3 to the system.
tracker.get();                         // Sorted locations: branford, orlando, alps, bradford, orland. 
                                       // Return &quot;bradford&quot;. 
tracker.add(&quot;alpine&quot;, 2);              // Add location with name=&quot;alpine&quot; and score=2 to the system.
tracker.get();                         // Sorted locations: branford, orlando, alpine, alps, bradford, orland. 
                                       // Return &quot;bradford&quot;. 
tracker.get();                         // Sorted locations: branford, orlando, alpine, alps, bradford, orland. 
                                       // Return &quot;orland&quot;.
&lt;/p&gt;</pre>



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



<ul class="wp-block-list"><li><code>name</code>&nbsp;consists of lowercase English letters, and is unique among all locations.</li><li><code>1 &lt;= name.length &lt;= 10</code></li><li><code>1 &lt;= score &lt;= 10<sup>5</sup></code></li><li>At any time, the number of calls to&nbsp;<code>get</code>&nbsp;does not exceed the number of calls to&nbsp;<code>add</code>.</li><li>At most&nbsp;<code>4 * 10<sup>4</sup></code>&nbsp;calls&nbsp;<strong>in total</strong>&nbsp;will be made to&nbsp;<code>add</code>&nbsp;and&nbsp;<code>get</code>.</li></ul>



<h2 class="wp-block-heading"><strong>Solution: TreeSet w/ Iterator</strong></h2>



<p>Use a treeset to store all the entries and use a iterator that points to the entry to return. When inserting a new entry into the tree, if it&#8217;s higher than the current element then let the iterator go backward one step. </p>



<p>Time complexity:  add O(logn) / get O(1)</p>



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class SORTracker {
public:
  SORTracker() {}

  void add(string name, int score) {    
    if (*s.emplace(-score, name).first &lt; *cit) --cit;
  }

  string get() {
    return (cit++)-&gt;second;
  }
private:
  set&lt;pair&lt;int, string&gt;&gt; s;
  // Note: cit points to begin(s) after first insertion.
  set&lt;pair&lt;int, string&gt;&gt;::const_iterator cit = end(s);
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/data-structure/leetcode-2102-sequentially-ordinal-rank-tracker/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2007. Find Original Array From Doubled Array</title>
		<link>https://zxi.mytechroad.com/blog/hashtable/leetcode-2007-find-original-array-from-doubled-array/</link>
					<comments>https://zxi.mytechroad.com/blog/hashtable/leetcode-2007-find-original-array-from-doubled-array/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Thu, 25 Nov 2021 20:57:49 +0000</pubDate>
				<category><![CDATA[Hashtable]]></category>
		<category><![CDATA[hashtable]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[multiset]]></category>
		<category><![CDATA[treeset]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8766</guid>

					<description><![CDATA[An integer array&#160;original&#160;is transformed into a&#160;doubled&#160;array&#160;changed&#160;by appending&#160;twice the value&#160;of every element in&#160;original, and then randomly&#160;shuffling&#160;the resulting array. Given an array&#160;changed, return&#160;original&#160;if&#160;changed&#160;is a&#160;doubled&#160;array. If&#160;changed&#160;is not a&#160;doubled&#160;array,&#8230;]]></description>
										<content:encoded><![CDATA[
<p>An integer array&nbsp;<code>original</code>&nbsp;is transformed into a&nbsp;<strong>doubled</strong>&nbsp;array&nbsp;<code>changed</code>&nbsp;by appending&nbsp;<strong>twice the value</strong>&nbsp;of every element in&nbsp;<code>original</code>, and then randomly&nbsp;<strong>shuffling</strong>&nbsp;the resulting array.</p>



<p>Given an array&nbsp;<code>changed</code>, return&nbsp;<code>original</code><em>&nbsp;if&nbsp;</em><code>changed</code><em>&nbsp;is a&nbsp;<strong>doubled</strong>&nbsp;array. If&nbsp;</em><code>changed</code><em>&nbsp;is not a&nbsp;<strong>doubled</strong>&nbsp;array, return an empty array. The elements in</em>&nbsp;<code>original</code>&nbsp;<em>may be returned in&nbsp;<strong>any</strong>&nbsp;order</em>.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> changed = [1,3,4,2,6,8]
<strong>Output:</strong> [1,3,4]
<strong>Explanation:</strong> One possible original array could be [1,3,4]:
- Twice the value of 1 is 1 * 2 = 2.
- Twice the value of 3 is 3 * 2 = 6.
- Twice the value of 4 is 4 * 2 = 8.
Other original arrays could be [4,3,1] or [3,1,4].
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> changed = [6,3,0,1]
<strong>Output:</strong> []
<strong>Explanation:</strong> changed is not a doubled array.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> changed = [1]
<strong>Output:</strong> []
<strong>Explanation:</strong> changed is not a doubled array.
</pre>



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



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



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



<p>Start from the smallest number x, erase one x * 2 from the set.</p>



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  vector&lt;int&gt; findOriginalArray(vector&lt;int&gt;&amp; changed) {
    if (changed.size() &amp; 1) return {};
    const int n = changed.size() / 2;
    multiset&lt;int&gt; s(begin(changed), end(changed));    
    while (ans.size() != n) {
      int o = *begin(s);
      s.erase(begin(s));
      ans.push_back(o);
      auto it = s.find(o * 2);
      if (it == end(s)) return {};
      s.erase(it);
    }
    return ans;
  }
};</pre>
</div></div>



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



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  vector&lt;int&gt; findOriginalArray(vector&lt;int&gt;&amp; changed) {
    if (changed.size() &amp; 1) return {};
    const int n = changed.size() / 2;
    const int kMax = *max_element(begin(changed), end(changed));
    vector&lt;int&gt; m(kMax + 1);
    for (int x : changed) ++m[x];
    if (m[0] &amp; 1) return {};
    vector&lt;int&gt; ans(m[0] / 2, 0);
    for (int x = 1; ans.size() != n; ++x) {
      if (x * 2 &gt; kMax || m[x * 2] &lt; m[x]) return {};      
      ans.insert(end(ans), m[x], x);
      m[x * 2] -= m[x];   
    }
    return ans;
  }
};</pre>
</div></div>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/hashtable/leetcode-2007-find-original-array-from-doubled-array/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1845. Seat Reservation Manager</title>
		<link>https://zxi.mytechroad.com/blog/data-structure/leetcode-1845-seat-reservation-manager/</link>
					<comments>https://zxi.mytechroad.com/blog/data-structure/leetcode-1845-seat-reservation-manager/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 01 May 2021 22:28:54 +0000</pubDate>
				<category><![CDATA[Data Structure]]></category>
		<category><![CDATA[data structure]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[treeset]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8409</guid>

					<description><![CDATA[Design a system that manages the reservation state of&#160;n&#160;seats that are numbered from&#160;1&#160;to&#160;n. Implement the&#160;SeatManager&#160;class: SeatManager(int n)&#160;Initializes a&#160;SeatManager&#160;object that will manage&#160;n&#160;seats numbered from&#160;1&#160;to&#160;n. All seats&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Design a system that manages the reservation state of&nbsp;<code>n</code>&nbsp;seats that are numbered from&nbsp;<code>1</code>&nbsp;to&nbsp;<code>n</code>.</p>



<p>Implement the&nbsp;<code>SeatManager</code>&nbsp;class:</p>



<ul class="wp-block-list"><li><code>SeatManager(int n)</code>&nbsp;Initializes a&nbsp;<code>SeatManager</code>&nbsp;object that will manage&nbsp;<code>n</code>&nbsp;seats numbered from&nbsp;<code>1</code>&nbsp;to&nbsp;<code>n</code>. All seats are initially available.</li><li><code>int reserve()</code>&nbsp;Fetches the&nbsp;<strong>smallest-numbered</strong>&nbsp;unreserved seat, reserves it, and returns its number.</li><li><code>void unreserve(int seatNumber)</code>&nbsp;Unreserves the seat with the given&nbsp;<code>seatNumber</code>.</li></ul>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input</strong>
["SeatManager", "reserve", "reserve", "unreserve", "reserve", "reserve", "reserve", "reserve", "unreserve"]
[[5], [], [], [2], [], [], [], [], [5]]
<strong>Output</strong>

[null, 1, 2, null, 2, 3, 4, 5, null]

<strong>Explanation</strong> SeatManager seatManager = new SeatManager(5); // Initializes a SeatManager with 5 seats. seatManager.reserve(); // All seats are available, so return the lowest numbered seat, which is 1. seatManager.reserve(); // The available seats are [2,3,4,5], so return the lowest of them, which is 2. seatManager.unreserve(2); // Unreserve seat 2, so now the available seats are [2,3,4,5]. seatManager.reserve(); // The available seats are [2,3,4,5], so return the lowest of them, which is 2. seatManager.reserve(); // The available seats are [3,4,5], so return the lowest of them, which is 3. seatManager.reserve(); // The available seats are [4,5], so return the lowest of them, which is 4. seatManager.reserve(); // The only available seat is seat 5, so return 5. seatManager.unreserve(5); // Unreserve seat 5, so now the available seats are [5].
</pre>



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



<ul class="wp-block-list"><li><code>1 &lt;= n &lt;= 10<sup>5</sup></code></li><li><code>1 &lt;= seatNumber &lt;= n</code></li><li>For each call to&nbsp;<code>reserve</code>, it is guaranteed that there will be at least one unreserved seat.</li><li>For each call to&nbsp;<code>unreserve</code>, it is guaranteed that&nbsp;<code>seatNumber</code>&nbsp;will be reserved.</li><li>At most&nbsp;<code>10<sup>5</sup></code>&nbsp;calls&nbsp;<strong>in total</strong>&nbsp;will be made to&nbsp;<code>reserve</code>&nbsp;and&nbsp;<code>unreserve</code>.</li></ul>



<h2 class="wp-block-heading"><strong>Solution: TreeSet</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 SeatManager {
public:
  SeatManager(int n) {
    for (int i = 1; i &lt;= n; ++i)
      s_.insert(i);
  }

  int reserve() {    
    int seat = *begin(s_);
    s_.erase(begin(s_));    
    return seat;
  }

  void unreserve(int seatNumber) {
    s_.insert(seatNumber);    
  }
private:
  set&lt;int&gt; s_;
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/data-structure/leetcode-1845-seat-reservation-manager/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 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 fetchpriority="high" 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="(max-width: 960px) 100vw, 960px" /></figure>



<figure class="wp-block-image size-large"><img 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="(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 1606. Find Servers That Handled Most Number of Requests</title>
		<link>https://zxi.mytechroad.com/blog/simulation/leetcode-1606-find-servers-that-handled-most-number-of-requests/</link>
					<comments>https://zxi.mytechroad.com/blog/simulation/leetcode-1606-find-servers-that-handled-most-number-of-requests/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 03 Oct 2020 23:43:57 +0000</pubDate>
				<category><![CDATA[Simulation]]></category>
		<category><![CDATA[heap]]></category>
		<category><![CDATA[priority_queue]]></category>
		<category><![CDATA[simulation]]></category>
		<category><![CDATA[treeset]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7448</guid>

					<description><![CDATA[You have&#160;k&#160;servers numbered from&#160;0&#160;to&#160;k-1&#160;that are being used to handle multiple requests simultaneously. Each server has infinite computational capacity but&#160;cannot handle more than one request at&#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 1606. Find Servers That Handled Most Number of Requests - 刷题找工作 EP359" width="500" height="281" src="https://www.youtube.com/embed/9OqDLNyL8Fs?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 have&nbsp;<code>k</code>&nbsp;servers numbered from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>k-1</code>&nbsp;that are being used to handle multiple requests simultaneously. Each server has infinite computational capacity but&nbsp;<strong>cannot handle more than one request at a time</strong>. The requests are assigned to servers according to a specific algorithm:</p>



<ul class="wp-block-list"><li>The&nbsp;<code>i<sup>th</sup></code>&nbsp;(0-indexed) request arrives.</li><li>If all servers are busy, the request is dropped (not handled at all).</li><li>If the&nbsp;<code>(i % k)<sup>th</sup></code>&nbsp;server is available, assign the request to that server.</li><li>Otherwise, assign the request to the next available server (wrapping around the list of servers and starting from 0 if necessary). For example, if the&nbsp;<code>i<sup>th</sup></code>&nbsp;server is busy, try to assign the request to the&nbsp;<code>(i+1)<sup>th</sup></code>&nbsp;server, then the&nbsp;<code>(i+2)<sup>th</sup></code>&nbsp;server, and so on.</li></ul>



<p>You are given a&nbsp;<strong>strictly increasing</strong>&nbsp;array&nbsp;<code>arrival</code>&nbsp;of positive integers, where&nbsp;<code>arrival[i]</code>&nbsp;represents the arrival time of the&nbsp;<code>i<sup>th</sup></code>&nbsp;request, and another array&nbsp;<code>load</code>, where&nbsp;<code>load[i]</code>&nbsp;represents the load of the&nbsp;<code>i<sup>th</sup></code>&nbsp;request (the time it takes to complete). Your goal is to find the&nbsp;<strong>busiest server(s)</strong>. A server is considered&nbsp;<strong>busiest</strong>&nbsp;if it handled the most number of requests successfully among all the servers.</p>



<p>Return&nbsp;<em>a list containing the IDs (0-indexed) of the&nbsp;<strong>busiest server(s)</strong></em>. You may return the IDs in any order.</p>



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



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2020/09/08/load-1.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> k = 3, arrival = [1,2,3,4,5], load = [5,2,3,3,3] 
<strong>Output:</strong> [1] 
<strong>Explanation:</strong>
All of the servers start out available.
The first 3 requests are handled by the first 3 servers in order.
Request 3 comes in. Server 0 is busy, so it's assigned to the next available server, which is 1.
Request 4 comes in. It cannot be handled since all servers are busy, so it is dropped.
Servers 0 and 2 handled one request each, while server 1 handled two requests. Hence server 1 is the busiest server.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> k = 3, arrival = [1,2,3,4], load = [1,2,1,2]
<strong>Output:</strong> [0]
<strong>Explanation:</strong>
The first 3 requests are handled by first 3 servers.
Request 3 comes in. It is handled by server 0 since the server is available.
Server 0 handled two requests, while servers 1 and 2 handled one request each. Hence server 0 is the busiest server.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> k = 3, arrival = [1,2,3], load = [10,12,11]
<strong>Output:</strong> [0,1,2]
<strong>Explanation: </strong>Each server handles a single request, so they are all considered the busiest.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> k = 3, arrival = [1,2,3,4,8,9,10], load = [5,2,10,3,1,2,2]
<strong>Output:</strong> [1]
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> k = 1, arrival = [1], load = [1]
<strong>Output:</strong> [0]
</pre>



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



<ul class="wp-block-list"><li><code>1 &lt;= k &lt;= 10<sup>5</sup></code></li><li><code>1 &lt;= arrival.length, load.length &lt;= 10<sup>5</sup></code></li><li><code>arrival.length == load.length</code></li><li><code>1 &lt;= arrival[i], load[i] &lt;= 10<sup>9</sup></code></li><li><code>arrival</code>&nbsp;is&nbsp;<strong>strictly increasing</strong>.</li></ul>



<h2 class="wp-block-heading"><strong>Solution: Heap + TreeSet</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/10/1606-ep359-1.png" alt="" class="wp-image-7452" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/10/1606-ep359-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/10/1606-ep359-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/10/1606-ep359-1-768x432.png 768w" sizes="auto, (max-width: 960px) 100vw, 960px" /></figure>



<p>Use a min heap to store the release time -> server.<br>Use a treeset to track the current available servers.<br>For reach request, check whether servers can be released at that time.</p>



<p>Time complexity: O(nlogk)<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:
  vector&lt;int&gt; busiestServers(int k, vector&lt;int&gt;&amp; arrival, vector&lt;int&gt;&amp; load) {
    priority_queue&lt;pair&lt;int, int&gt;, vector&lt;pair&lt;int,int&gt;&gt;, greater&lt;&gt;&gt; q; // {release_time, server}
    set&lt;int&gt; servers;
    vector&lt;int&gt; requests(k);
    
    for (int i = 0; i &lt; k; ++i)
      servers.insert(i);
    
    for (int i = 0; i &lt; arrival.size(); ++i) {
      const int t = arrival[i];
      const int l = load[i];
      
      // Release servers. O(logk) per pop()
      while (!q.empty() &amp;&amp; q.top().first &lt;= t) {        
        servers.insert(q.top().second);  
        q.pop();
      }
      
      // Drop the request.
      if (servers.empty()) continue;
      
      // Find first avaiable one O(logk)
      auto it = servers.lower_bound(i % k);
      if (it == servers.end()) it = begin(servers);
      const int idx = *it;
      
      ++requests[idx];
      servers.erase(it);
      q.emplace(t + l, idx);
    }
    const int max_req = *max_element(begin(requests), end(requests));
    vector&lt;int&gt; ans;
    for (int i = 0; i &lt; k; ++i)
      if (requests[i] == max_req) ans.push_back(i);
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/simulation/leetcode-1606-find-servers-that-handled-most-number-of-requests/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
