<?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>data structure Archives - Huahua&#039;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/tag/data-structure/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog/tag/data-structure/</link>
	<description></description>
	<lastBuildDate>Mon, 04 Apr 2022 02:22:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.0.8</generator>

<image>
	<url>https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/cropped-photo-32x32.jpg</url>
	<title>data structure Archives - Huahua&#039;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog/tag/data-structure/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>花花酱 LeetCode 2227. Encrypt and Decrypt Strings</title>
		<link>https://zxi.mytechroad.com/blog/data-structure/leetcode-2227-encrypt-and-decrypt-strings/</link>
					<comments>https://zxi.mytechroad.com/blog/data-structure/leetcode-2227-encrypt-and-decrypt-strings/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 03 Apr 2022 09:39:44 +0000</pubDate>
				<category><![CDATA[Data Structure]]></category>
		<category><![CDATA[data structure]]></category>
		<category><![CDATA[dictionary]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[string]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9626</guid>

					<description><![CDATA[<p>You are given a character array&#160;keys&#160;containing&#160;unique&#160;characters and a string array&#160;values&#160;containing strings of length 2. You are also given another string array&#160;dictionary&#160;that contains all permitted original&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/data-structure/leetcode-2227-encrypt-and-decrypt-strings/">花花酱 LeetCode 2227. Encrypt and Decrypt Strings</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>You are given a character array&nbsp;<code>keys</code>&nbsp;containing&nbsp;<strong>unique</strong>&nbsp;characters and a string array&nbsp;<code>values</code>&nbsp;containing strings of length 2. You are also given another string array&nbsp;<code>dictionary</code>&nbsp;that contains all permitted original strings after decryption. You should implement a data structure that can encrypt or decrypt a&nbsp;<strong>0-indexed</strong>&nbsp;string.</p>



<p>A string is&nbsp;<strong>encrypted</strong>&nbsp;with the following process:</p>



<ol><li>For each character&nbsp;<code>c</code>&nbsp;in the string, we find the index&nbsp;<code>i</code>&nbsp;satisfying&nbsp;<code>keys[i] == c</code>&nbsp;in&nbsp;<code>keys</code>.</li><li>Replace&nbsp;<code>c</code>&nbsp;with&nbsp;<code>values[i]</code>&nbsp;in the string.</li></ol>



<p>A string is&nbsp;<strong>decrypted</strong>&nbsp;with the following process:</p>



<ol><li>For each substring&nbsp;<code>s</code>&nbsp;of length 2 occurring at an even index in the string, we find an&nbsp;<code>i</code>&nbsp;such that&nbsp;<code>values[i] == s</code>. If there are multiple valid&nbsp;<code>i</code>, we choose&nbsp;<strong>any</strong>&nbsp;one of them. This means a string could have multiple possible strings it can decrypt to.</li><li>Replace&nbsp;<code>s</code>&nbsp;with&nbsp;<code>keys[i]</code>&nbsp;in the string.</li></ol>



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



<ul><li><code>Encrypter(char[] keys, String[] values, String[] dictionary)</code>&nbsp;Initializes the&nbsp;<code>Encrypter</code>&nbsp;class with&nbsp;<code>keys, values</code>, and&nbsp;<code>dictionary</code>.</li><li><code>String encrypt(String word1)</code>&nbsp;Encrypts&nbsp;<code>word1</code>&nbsp;with the encryption process described above and returns the encrypted string.</li><li><code>int decrypt(String word2)</code>&nbsp;Returns the number of possible strings&nbsp;<code>word2</code>&nbsp;could decrypt to that also appear in&nbsp;<code>dictionary</code>.</li></ul>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input</strong>
["Encrypter", "encrypt", "decrypt"]
[[['a', 'b', 'c', 'd'], ["ei", "zf", "ei", "am"], ["abcd", "acbd", "adbc", "badc", "dacb", "cadb", "cbda", "abad"]], ["abcd"], ["eizfeiam"]]
<strong>Output</strong>
</pre>


<p>[null, &#8220;eizfeiam&#8221;, 2]</p>



<p><strong>Explanation</strong> Encrypter encrypter = new Encrypter([[&#8216;a&#8217;, &#8216;b&#8217;, &#8216;c&#8217;, &#8216;d&#8217;], [&#8220;ei&#8221;, &#8220;zf&#8221;, &#8220;ei&#8221;, &#8220;am&#8221;], [&#8220;abcd&#8221;, &#8220;acbd&#8221;, &#8220;adbc&#8221;, &#8220;badc&#8221;, &#8220;dacb&#8221;, &#8220;cadb&#8221;, &#8220;cbda&#8221;, &#8220;abad&#8221;]); encrypter.encrypt(&#8220;abcd&#8221;); // return &#8220;eizfeiam&#8221;. &nbsp; // &#8216;a&#8217; maps to &#8220;ei&#8221;, &#8216;b&#8217; maps to &#8220;zf&#8221;, &#8216;c&#8217; maps to &#8220;ei&#8221;, and &#8216;d&#8217; maps to &#8220;am&#8221;. encrypter.decrypt(&#8220;eizfeiam&#8221;); // return 2. // &#8220;ei&#8221; can map to &#8216;a&#8217; or &#8216;c&#8217;, &#8220;zf&#8221; maps to &#8216;b&#8217;, and &#8220;am&#8221; maps to &#8216;d&#8217;. // Thus, the possible strings after decryption are &#8220;abad&#8221;, &#8220;cbad&#8221;, &#8220;abcd&#8221;, and &#8220;cbcd&#8221;. // 2 of those strings, &#8220;abad&#8221; and &#8220;abcd&#8221;, appear in dictionary, so the answer is 2.</p>



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



<ul><li><code>1 &lt;= keys.length == values.length &lt;= 26</code></li><li><code>values[i].length == 2</code></li><li><code>1 &lt;= dictionary.length &lt;= 100</code></li><li><code>1 &lt;= dictionary[i].length &lt;= 100</code></li><li>All&nbsp;<code>keys[i]</code>&nbsp;and&nbsp;<code>dictionary[i]</code>&nbsp;are&nbsp;<strong>unique</strong>.</li><li><code>1 &lt;= word1.length &lt;= 2000</code></li><li><code>1 &lt;= word2.length &lt;= 200</code></li><li>All&nbsp;<code>word1[i]</code>&nbsp;appear in&nbsp;<code>keys</code>.</li><li><code>word2.length</code>&nbsp;is even.</li><li><code>keys</code>,&nbsp;<code>values[i]</code>,&nbsp;<code>dictionary[i]</code>,&nbsp;<code>word1</code>, and&nbsp;<code>word2</code>&nbsp;only contain lowercase English letters.</li><li>At most&nbsp;<code>200</code>&nbsp;calls will be made to&nbsp;<code>encrypt</code>&nbsp;and&nbsp;<code>decrypt</code>&nbsp;<strong>in total</strong>.</li></ul>



<h2><strong>Solution: </strong></h2>



<p>For encryption, follow the instruction. Time complexity: O(len(word)) = O(2000)<br>For decryption, try all words in the dictionary and encrypt them and compare the encrypted string with the word to decrypt. Time <meta charset="utf-8">complexity: O(sum(len(word_in_dict))) = O(100*100)</p>



<p>Worst case: 200 calls to decryption, T = 200 * O(100 * 100) = O(2*10<sup>6</sup>)</p>



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

<pre class="crayon-plain-tag">// Author: Huahua
class Encrypter {
public:
  Encrypter(vector&lt;char&gt;&amp; keys, 
            vector&lt;string&gt;&amp; values, 
            vector&lt;string&gt;&amp; dictionary):
        vals(26),
        dict(dictionary) {
    for (size_t i = 0; i &lt; keys.size(); ++i)
      vals[keys[i] - 'a'] = values[i];  
  }

  string encrypt(string word1) {
    string ans;
    for (char c : word1)
      ans += vals[c - 'a'];
    return ans;
  }

  int decrypt(string word2) {
    return count_if(begin(dict), end(dict), [&amp;](const string&amp; w){ 
      return encrypt(w) == word2;
    });    
  }
private:
  vector&lt;string&gt; vals;
  vector&lt;string&gt; dict;
};</pre>
</div></div>



<h2><strong>Optimization</strong></h2>



<p>Pre-compute answer for all the words in dictionary.</p>



<p>decrypt: Time complexity: O(1)</p>



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

<pre class="crayon-plain-tag">// Author: Huahua
class Encrypter {
public:
  Encrypter(vector&lt;char&gt;&amp; keys, 
            vector&lt;string&gt;&amp; values, 
            vector&lt;string&gt;&amp; dictionary):
        vals(26) {
    for (size_t i = 0; i &lt; keys.size(); ++i)
      vals[keys[i] - 'a'] = values[i];  
    for (const string&amp; w : dictionary)
      ++counts[encrypt(w)];
  }

  string encrypt(string word1) {
    string ans;
    for (char c : word1)
      ans += vals[c - 'a'];
    return ans;
  }

  int decrypt(string word2) {
    auto it = counts.find(word2);
    return it == counts.end() ? 0 : it-&gt;second;
  }
private:
  vector&lt;string&gt; vals;  
  unordered_map&lt;string, int&gt; counts;
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/data-structure/leetcode-2227-encrypt-and-decrypt-strings/">花花酱 LeetCode 2227. Encrypt and Decrypt Strings</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/data-structure/leetcode-2227-encrypt-and-decrypt-strings/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[<p>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;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/data-structure/leetcode-2102-sequentially-ordinal-rank-tracker/">花花酱 LeetCode 2102. Sequentially Ordinal Rank Tracker</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>A 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><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><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="crayon-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><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><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="crayon-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>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/data-structure/leetcode-2102-sequentially-ordinal-rank-tracker/">花花酱 LeetCode 2102. Sequentially Ordinal Rank Tracker</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/data-structure/leetcode-2102-sequentially-ordinal-rank-tracker/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 211. Design Add and Search Words Data Structure</title>
		<link>https://zxi.mytechroad.com/blog/data-structure/leetcode-211-design-add-and-search-words-data-structure/</link>
					<comments>https://zxi.mytechroad.com/blog/data-structure/leetcode-211-design-add-and-search-words-data-structure/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 06 Dec 2021 03:55:03 +0000</pubDate>
				<category><![CDATA[Data Structure]]></category>
		<category><![CDATA[data structure]]></category>
		<category><![CDATA[hashtable]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[string]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9050</guid>

					<description><![CDATA[<p>Design a data structure that supports adding new words and finding if a string matches any previously added string. Implement the&#160;WordDictionary&#160;class: WordDictionary()&#160;Initializes the object. void&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/data-structure/leetcode-211-design-add-and-search-words-data-structure/">花花酱 LeetCode 211. Design Add and Search Words Data Structure</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Design a data structure that supports adding new words and finding if a string matches any previously added string.</p>



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



<ul><li><code>WordDictionary()</code>&nbsp;Initializes the object.</li><li><code>void addWord(word)</code>&nbsp;Adds&nbsp;<code>word</code>&nbsp;to the data structure, it can be matched later.</li><li><code>bool search(word)</code>&nbsp;Returns&nbsp;<code>true</code>&nbsp;if there is any string in the data structure that matches&nbsp;<code>word</code>&nbsp;or&nbsp;<code>false</code>&nbsp;otherwise.&nbsp;<code>word</code>&nbsp;may contain dots&nbsp;<code>'.'</code>&nbsp;where dots can be matched with any letter.</li></ul>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input</strong>
["WordDictionary","addWord","addWord","addWord","search","search","search","search"]
[[],["bad"],["dad"],["mad"],["pad"],["bad"],[".ad"],["b.."]]
<strong>Output</strong>
[null,null,null,null,false,true,true,true]
<strong>Explanation</strong> 
WordDictionary wordDictionary = new WordDictionary(); 
wordDictionary.addWord("bad"); 
wordDictionary.addWord("dad"); 
wordDictionary.addWord("mad"); 
wordDictionary.search("pad"); // return False 
wordDictionary.search("bad"); // return True 
wordDictionary.search(".ad"); // return True 
wordDictionary.search("b.."); // return True
</pre>



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



<ul><li><code>1 &lt;= word.length &lt;= 500</code></li><li><code>word</code>&nbsp;in&nbsp;<code>addWord</code>&nbsp;consists lower-case English letters.</li><li><code>word</code>&nbsp;in&nbsp;<code>search</code>&nbsp;consist of&nbsp;&nbsp;<code>'.'</code>&nbsp;or lower-case English letters.</li><li>At most&nbsp;<code>50000</code>&nbsp;calls will be made to&nbsp;<code>addWord</code>&nbsp;and&nbsp;<code>search</code>.</li></ul>



<h2><strong>Solution: Hashtables</strong></h2>



<p>The first hashtable stores all the words, if there is no dot in the search pattern. Do a full match.</p>



<p>There are also per length hashtable to store words of length k. And do a brute force match.</p>



<p>Time complexity: Init: O(n*l)<br>search: best: O(l) worst: O(n*l)</p>



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

<pre class="crayon-plain-tag">// Author: Huahua
class WordDictionary {
public:
  // Adds a word into the data structure.
  void addWord(string word) {
    words.insert(word);
    ws[word.length()].insert(word);
  }

  // Returns if the word is in the data structure. A word could
  // contain the dot character '.' to represent any one letter.
  bool search(string word) {
    if (word.find(&quot;.&quot;) == string::npos)
      return words.count(word);
    
    for (const string&amp; w : ws[word.length()])
      if (match(word, w)) return true;    

    return false;
  }
    
  bool match(const string&amp; p, const string&amp; w) {
    for (int i = 0; i &lt; p.length(); ++i) {
      if (p[i] == '.') continue;
      if (p[i] != w[i]) return false;
    }
    return true;
  }
private:
    unordered_set&lt;string&gt; words;
    unordered_map&lt;int, unordered_set&lt;string&gt;&gt; ws;
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/data-structure/leetcode-211-design-add-and-search-words-data-structure/">花花酱 LeetCode 211. Design Add and Search Words Data Structure</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/data-structure/leetcode-211-design-add-and-search-words-data-structure/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 155. Min Stack</title>
		<link>https://zxi.mytechroad.com/blog/stack/leetcode-155-min-stack/</link>
					<comments>https://zxi.mytechroad.com/blog/stack/leetcode-155-min-stack/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 28 Nov 2021 22:01:10 +0000</pubDate>
				<category><![CDATA[Stack]]></category>
		<category><![CDATA[data structure]]></category>
		<category><![CDATA[easy]]></category>
		<category><![CDATA[stack]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8870</guid>

					<description><![CDATA[<p>Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. Implement the&#160;MinStack&#160;class: MinStack()&#160;initializes the stack object. void push(int val)&#160;pushes&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/stack/leetcode-155-min-stack/">花花酱 LeetCode 155. Min Stack</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.</p>



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



<ul><li><code>MinStack()</code>&nbsp;initializes the stack object.</li><li><code>void push(int val)</code>&nbsp;pushes the element&nbsp;<code>val</code>&nbsp;onto the stack.</li><li><code>void pop()</code>&nbsp;removes the element on the top of the stack.</li><li><code>int top()</code>&nbsp;gets the top element of the stack.</li><li><code>int getMin()</code>&nbsp;retrieves the minimum element in the stack.</li></ul>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input</strong>
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]

<strong>Output</strong>
</pre>


<p>[null,null,null,null,-3,null,0,-2]</p>



<p><strong>Explanation</strong> MinStack minStack = new MinStack(); minStack.push(-2); minStack.push(0); minStack.push(-3); minStack.getMin(); // return -3 minStack.pop(); minStack.top(); // return 0 minStack.getMin(); // return -2</p>



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



<ul><li><code>-2<sup>31</sup>&nbsp;&lt;= val &lt;= 2<sup>31</sup>&nbsp;- 1</code></li><li>Methods&nbsp;<code>pop</code>,&nbsp;<code>top</code>&nbsp;and&nbsp;<code>getMin</code>&nbsp;operations will always be called on&nbsp;<strong>non-empty</strong>&nbsp;stacks.</li><li>At most&nbsp;<code>3 * 10<sup>4</sup></code>&nbsp;calls will be made to&nbsp;<code>push</code>,&nbsp;<code>pop</code>,&nbsp;<code>top</code>, and&nbsp;<code>getMin</code>.</li></ul>



<h2><strong>Solution 1: Two Stack</strong>s</h2>



<p>One normal stack, one monotonic stack to store the min values.</p>



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



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

<pre class="crayon-plain-tag">// Author: Huahua
class MinStack {
public:
  void push(int x) {
    m_data.push(x);
    if (m_s.empty() || x &lt;= m_s.top())
      m_s.push(x);
  }

  void pop() {
    if (!m_s.empty() &amp;&amp; m_data.top() == m_s.top())
      m_s.pop();
    m_data.pop();
  }

  int top() {
    return m_data.top();
  }

  int getMin() {
    return m_s.empty() ? m_data.top() : m_s.top();
  }
private:
  stack&lt;int&gt; m_data;
  stack&lt;int&gt; m_s;
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/stack/leetcode-155-min-stack/">花花酱 LeetCode 155. Min Stack</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/stack/leetcode-155-min-stack/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1865. Finding Pairs With a Certain Sum</title>
		<link>https://zxi.mytechroad.com/blog/hashtable/leetcode-1865-finding-pairs-with-a-certain-sum/</link>
					<comments>https://zxi.mytechroad.com/blog/hashtable/leetcode-1865-finding-pairs-with-a-certain-sum/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Thu, 05 Aug 2021 05:48:38 +0000</pubDate>
				<category><![CDATA[Hashtable]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[data structure]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[hashtable]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8471</guid>

					<description><![CDATA[<p>You are given two integer arrays&#160;nums1&#160;and&#160;nums2. You are tasked to implement a data structure that supports queries of two types: Add&#160;a positive integer to an&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/hashtable/leetcode-1865-finding-pairs-with-a-certain-sum/">花花酱 LeetCode 1865. Finding Pairs With a Certain Sum</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>You are given two integer arrays&nbsp;<code>nums1</code>&nbsp;and&nbsp;<code>nums2</code>. You are tasked to implement a data structure that supports queries of two types:</p>



<ol><li><strong>Add</strong>&nbsp;a positive integer to an element of a given index in the array&nbsp;<code>nums2</code>.</li><li><strong>Count</strong>&nbsp;the number of pairs&nbsp;<code>(i, j)</code>&nbsp;such that&nbsp;<code>nums1[i] + nums2[j]</code>&nbsp;equals a given value (<code>0 &lt;= i &lt; nums1.length</code>&nbsp;and&nbsp;<code>0 &lt;= j &lt; nums2.length</code>).</li></ol>



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



<ul><li><code>FindSumPairs(int[] nums1, int[] nums2)</code>&nbsp;Initializes the&nbsp;<code>FindSumPairs</code>&nbsp;object with two integer arrays&nbsp;<code>nums1</code>&nbsp;and&nbsp;<code>nums2</code>.</li><li><code>void add(int index, int val)</code>&nbsp;Adds&nbsp;<code>val</code>&nbsp;to&nbsp;<code>nums2[index]</code>, i.e., apply&nbsp;<code>nums2[index] += val</code>.</li><li><code>int count(int tot)</code>&nbsp;Returns the number of pairs&nbsp;<code>(i, j)</code>&nbsp;such that&nbsp;<code>nums1[i] + nums2[j] == tot</code>.</li></ul>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input</strong>
["FindSumPairs", "count", "add", "count", "count", "add", "add", "count"]
[[[1, 1, 2, 2, 2, 3], [1, 4, 5, 2, 5, 4]], [7], [3, 2], [8], [4], [0, 1], [1, 1], [7]]
<strong>Output</strong>
[null, 8, null, 2, 1, null, null, 11]
<strong>Explanation</strong>
FindSumPairs findSumPairs = new FindSumPairs([1, 1, 2, 2, 2, 3], [1, 4, 5, 2, 5, 4]);
findSumPairs.count(7); // return 8; pairs (2,2), (3,2), (4,2), (2,4), (3,4), (4,4) make 2 + 5 and pairs (5,1), (5,5) make 3 + 4
findSumPairs.add(3, 2); // now nums2 = [1,4,5,<strong>4</strong>,5,4] 
findSumPairs.count(8); // return 2; pairs (5,2), (5,4) make 3 + 5 
findSumPairs.count(4); // return 1; pair (5,0) makes 3 + 1 
findSumPairs.add(0, 1); // now nums2 = [<strong>2</strong>,4,5,4,5,4] 
findSumPairs.add(1, 1); // now nums2 = [2,<strong>5</strong>,5,4,5,4] 
findSumPairs.count(7); // return 11; pairs (2,1), (2,2), (2,4), (3,1), (3,2), (3,4), (4,1), (4,2), (4,4) make 2 + 5 and pairs (5,3), (5,5) make 3 + 4
</pre>



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



<ul><li><code>1 &lt;= nums1.length &lt;= 1000</code></li><li><code>1 &lt;= nums2.length &lt;= 10<sup>5</sup></code></li><li><code>1 &lt;= nums1[i] &lt;= 10<sup>9</sup></code></li><li><code>1 &lt;= nums2[i] &lt;= 10<sup>5</sup></code></li><li><code>0 &lt;= index &lt; nums2.length</code></li><li><code>1 &lt;= val &lt;= 10<sup>5</sup></code></li><li><code>1 &lt;= tot &lt;= 10<sup>9</sup></code></li><li>At most&nbsp;<code>1000</code>&nbsp;calls are made to&nbsp;<code>add</code>&nbsp;and&nbsp;<code>count</code>&nbsp;<strong>each</strong>.</li></ul>



<h2><strong>Solution: HashTable</strong></h2>



<p>Note nums1 and nums2 are unbalanced. Brute force method will take O(m*n) = O(10<sup>3</sup>*10<sup>5</sup>) = O(10<sup>8</sup>) for each count call which will TLE. We could use a hashtable to store the counts of elements from nums2, and only iterate over nums1 to reduce the time complexity.</p>



<p>Time complexity:</p>



<p>init: O(m) + O(n)<br>add: O(1)<br>count: O(m)</p>



<p>Total time is less than O(10<sup>6</sup>)</p>



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



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

<pre class="crayon-plain-tag">// Author: Huahua
class FindSumPairs {
public:
  FindSumPairs(vector&lt;int&gt;&amp; nums1, 
               vector&lt;int&gt;&amp; nums2): nums1_(nums1), nums2_(nums2) {
    for (int x : nums2_) ++freq_[x];
  }

  void add(int index, int val) {
    if (--freq_[nums2_[index]] == 0)
      freq_.erase(nums2_[index]);
    ++freq_[nums2_[index] += val];
  }

  int count(int tot) {
    int ans = 0;
    for (int a : nums1_) {
      auto it = freq_.find(tot - a);
      if (it != freq_.end()) ans += it-&gt;second;
    }
    return ans;
  }
private:  
  vector&lt;int&gt; nums1_;
  vector&lt;int&gt; nums2_;
  unordered_map&lt;int, int&gt; freq_;
};</pre>

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

<pre class="crayon-plain-tag"># Author: Huahua
class FindSumPairs:
  def __init__(self, nums1: List[int], nums2: List[int]):
    self.nums1 = nums1
    self.nums2 = nums2
    self.freq = Counter(nums2)


  def add(self, index: int, val: int) -&gt; None:
    self.freq.subtract((self.nums2[index],))
    self.nums2[index] += val
    self.freq.update((self.nums2[index],))


  def count(self, tot: int) -&gt; int:
    return sum(self.freq[tot - a] for a in self.nums1)</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/hashtable/leetcode-1865-finding-pairs-with-a-certain-sum/">花花酱 LeetCode 1865. Finding Pairs With a Certain Sum</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/hashtable/leetcode-1865-finding-pairs-with-a-certain-sum/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[<p>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;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/data-structure/leetcode-1845-seat-reservation-manager/">花花酱 LeetCode 1845. Seat Reservation Manager</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>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><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><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><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="crayon-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>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/data-structure/leetcode-1845-seat-reservation-manager/">花花酱 LeetCode 1845. Seat Reservation Manager</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/data-structure/leetcode-1845-seat-reservation-manager/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1825. Finding MK Average</title>
		<link>https://zxi.mytechroad.com/blog/data-structure/leetcode-1825-finding-mk-average/</link>
					<comments>https://zxi.mytechroad.com/blog/data-structure/leetcode-1825-finding-mk-average/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Wed, 14 Apr 2021 02:58:09 +0000</pubDate>
				<category><![CDATA[Data Structure]]></category>
		<category><![CDATA[data structure]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[multiset]]></category>
		<category><![CDATA[ordered set]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8350</guid>

					<description><![CDATA[<p>You are given two integers,&#160;m&#160;and&#160;k, and a stream of integers. You are tasked to implement a data structure that calculates the&#160;MKAverage&#160;for the stream. The&#160;MKAverage&#160;can be&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/data-structure/leetcode-1825-finding-mk-average/">花花酱 LeetCode 1825. Finding MK Average</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>You are given two integers,&nbsp;<code>m</code>&nbsp;and&nbsp;<code>k</code>, and a stream of integers. You are tasked to implement a data structure that calculates the&nbsp;<strong>MKAverage</strong>&nbsp;for the stream.</p>



<p>The&nbsp;<strong>MKAverage</strong>&nbsp;can be calculated using these steps:</p>



<ol><li>If the number of the elements in the stream is less than&nbsp;<code>m</code>&nbsp;you should consider the&nbsp;<strong>MKAverage</strong>&nbsp;to be&nbsp;<code>-1</code>. Otherwise, copy the last&nbsp;<code>m</code>&nbsp;elements of the stream to a separate container.</li><li>Remove the smallest&nbsp;<code>k</code>&nbsp;elements and the largest&nbsp;<code>k</code>&nbsp;elements from the container.</li><li>Calculate the average value for the rest of the elements&nbsp;<strong>rounded down to the nearest integer</strong>.</li></ol>



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



<ul><li><code>MKAverage(int m, int k)</code>&nbsp;Initializes the&nbsp;<strong>MKAverage</strong>&nbsp;object with an empty stream and the two integers&nbsp;<code>m</code>&nbsp;and&nbsp;<code>k</code>.</li><li><code>void addElement(int num)</code>&nbsp;Inserts a new element&nbsp;<code>num</code>&nbsp;into the stream.</li><li><code>int calculateMKAverage()</code>&nbsp;Calculates and returns the&nbsp;<strong>MKAverage</strong>&nbsp;for the current stream&nbsp;<strong>rounded down to the nearest integer</strong>.</li></ul>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input</strong>
["MKAverage", "addElement", "addElement", "calculateMKAverage", "addElement", "calculateMKAverage", "addElement", "addElement", "addElement", "calculateMKAverage"]
[[3, 1], [3], [1], [], [10], [], [5], [5], [5], []]
<strong>Output</strong>
[null, null, null, -1, null, 3, null, null, null, 5]
<p><strong>Explanation</strong> MKAverage obj = new MKAverage(3, 1); obj.addElement(3); // current elements are [3] obj.addElement(1); // current elements are [3,1] obj.calculateMKAverage(); // return -1, because m = 3 and only 2 elements exist. obj.addElement(10); // current elements are [3,1,10] obj.calculateMKAverage(); // The last 3 elements are [3,1,10]. // After removing smallest and largest 1 element the container will be <code>[3]. // The average of [3] equals 3/1 = 3, return 3 obj.addElement(5); // current elements are [3,1,10,5] obj.addElement(5); // current elements are [3,1,10,5,5] obj.addElement(5); // current elements are [3,1,10,5,5,5] obj.calculateMKAverage(); // The last 3 elements are [5,5,5]. // After removing smallest and largest 1 element the container will be <code>[5]. // The average of [5] equals 5/1 = 5, return 5</code></code></p>
</pre>



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



<ul><li><code>3 &lt;= m &lt;= 10<sup>5</sup></code></li><li><code>1 &lt;= k*2 &lt; m</code></li><li><code>1 &lt;= num &lt;= 10<sup>5</sup></code></li><li>At most&nbsp;<code>10<sup>5</sup></code>&nbsp;calls will be made to&nbsp;<code>addElement</code>&nbsp;and&nbsp;<code>calculateMKAverage</code>.</li></ul>



<h2><strong>Solution 1: Multiset * 3</strong></h2>



<p>Use three multiset to track the left part (smallest k elements), right part (largest k elements) and mid (middle part of m &#8211; 2*k elements).</p>



<p>Time complexity: addElememt: O(logn), average: O(1)<br>Space complexity: O(n)</p>



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

<pre class="crayon-plain-tag">class MKAverage {
public:
  MKAverage(int m, int k): 
    sum(0), m(m), k(k), n(m - 2*k) {}

  void addElement(int num) {
    if (q.size() == m) {      
      remove(q.front());
      q.pop();
    }
    q.push(num);
    add(num);
  }

  int calculateMKAverage() {    
    return (q.size() &lt; m) ? -1 : sum / n;
  }
private:
  void add(int x) {
    left.insert(x);
    
    if (left.size() &gt; k) {
      auto it = prev(end(left));
      sum += *it;
      mid.insert(*it);      
      left.erase(it);
    }
    
    if (mid.size() &gt; n) {
      auto it = prev(end(mid));
      sum -= *it; 
      right.insert(*it);
      mid.erase(it);
    }
  }
  
  void remove(int x) {
    if (x &lt;= *rbegin(left)) {
      left.erase(left.find(x));
    } else if (x &lt;= *rbegin(mid)) {
      sum -= x;
      mid.erase(mid.find(x));
    } else {
      right.erase(right.find(x));
    }
    
    if (left.size() &lt; k) {
      auto it = begin(mid);
      sum -= *it;
      left.insert(*it);
      mid.erase(it);
    }
    
    if (mid.size() &lt; n) {
      auto it = begin(right);
      sum += *it;
      mid.insert(*it);
      right.erase(it);
    }
  }
  
  queue&lt;int&gt; q;
  multiset&lt;int&gt; left, mid, right;  
  long sum;
  const int m;
  const int k;
  const int n;
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/data-structure/leetcode-1825-finding-mk-average/">花花酱 LeetCode 1825. Finding MK Average</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/data-structure/leetcode-1825-finding-mk-average/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1670. Design Front Middle Back Queue</title>
		<link>https://zxi.mytechroad.com/blog/list/leetcode-1670-design-front-middle-back-queue/</link>
					<comments>https://zxi.mytechroad.com/blog/list/leetcode-1670-design-front-middle-back-queue/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 28 Nov 2020 20:00:04 +0000</pubDate>
				<category><![CDATA[List]]></category>
		<category><![CDATA[data structure]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[iterator]]></category>
		<category><![CDATA[list]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7725</guid>

					<description><![CDATA[<p>Design a queue that supports&#160;push&#160;and&#160;pop&#160;operations in the front, middle, and back. Implement the&#160;FrontMiddleBack&#160;class: FrontMiddleBack()&#160;Initializes the queue. void pushFront(int val)&#160;Adds&#160;val&#160;to the&#160;front&#160;of the queue. void pushMiddle(int val)&#160;Adds&#160;val&#160;to&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/list/leetcode-1670-design-front-middle-back-queue/">花花酱 LeetCode 1670. Design Front Middle Back Queue</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Design a queue that supports&nbsp;<code>push</code>&nbsp;and&nbsp;<code>pop</code>&nbsp;operations in the front, middle, and back.</p>



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



<ul><li><code>FrontMiddleBack()</code>&nbsp;Initializes the queue.</li><li><code>void pushFront(int val)</code>&nbsp;Adds&nbsp;<code>val</code>&nbsp;to the&nbsp;<strong>front</strong>&nbsp;of the queue.</li><li><code>void pushMiddle(int val)</code>&nbsp;Adds&nbsp;<code>val</code>&nbsp;to the&nbsp;<strong>middle</strong>&nbsp;of the queue.</li><li><code>void pushBack(int val)</code>&nbsp;Adds&nbsp;<code>val</code>&nbsp;to the&nbsp;<strong>back</strong>&nbsp;of the queue.</li><li><code>int popFront()</code>&nbsp;Removes the&nbsp;<strong>front</strong>&nbsp;element of the queue and returns it. If the queue is empty, return&nbsp;<code>-1</code>.</li><li><code>int popMiddle()</code>&nbsp;Removes the&nbsp;<strong>middle</strong>&nbsp;element of the queue and returns it. If the queue is empty, return&nbsp;<code>-1</code>.</li><li><code>int popBack()</code>&nbsp;Removes the&nbsp;<strong>back</strong>&nbsp;element of the queue and returns it. If the queue is empty, return&nbsp;<code>-1</code>.</li></ul>



<p><strong>Notice</strong>&nbsp;that when there are&nbsp;<strong>two</strong>&nbsp;middle position choices, the operation is performed on the&nbsp;<strong>frontmost</strong>&nbsp;middle position choice. For example:</p>



<ul><li>Pushing&nbsp;<code>6</code>&nbsp;into the middle of&nbsp;<code>[1, 2, 3, 4, 5]</code>&nbsp;results in&nbsp;<code>[1, 2,&nbsp;6, 3, 4, 5]</code>.</li><li>Popping the middle from&nbsp;<code>[1, 2,&nbsp;3, 4, 5, 6]</code>&nbsp;returns&nbsp;<code>3</code>&nbsp;and results in&nbsp;<code>[1, 2, 4, 5, 6]</code>.</li></ul>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong>
["FrontMiddleBackQueue", "pushFront", "pushBack", "pushMiddle", "pushMiddle", "popFront", "popMiddle", "popMiddle", "popBack", "popFront"]
[[], [1], [2], [3], [4], [], [], [], [], []]
<strong>Output:</strong>
[null, null, null, null, null, 1, 3, 4, 2, -1]
<strong>Explanation:</strong>
FrontMiddleBackQueue q = new FrontMiddleBackQueue();
q.pushFront(1);   // [1]
q.pushBack(2);    // [1, 2]
q.pushMiddle(3);  // [1, 3, 2]
q.pushMiddle(4);  // [1, 4, 3, 2]
q.popFront();     // return 1 -&gt; [4, 3, 2]
q.popMiddle();    // return 3 -&gt; [4, 2]
q.popMiddle();    // return 4 -&gt; [2]
q.popBack();      // return 2 -&gt; []
q.popFront();     // return -1 -&gt; [] (The queue is empty)
</pre>



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



<ul><li><code>1 &lt;= val &lt;= 10<sup>9</sup></code></li><li>At most&nbsp;<code>1000</code>&nbsp;calls will be made to&nbsp;<code>pushFront</code>,&nbsp;<code>pushMiddle</code>,&nbsp;<code>pushBack</code>,&nbsp;<code>popFront</code>,&nbsp;<code>popMiddle</code>, and&nbsp;<code>popBack</code>.</li></ul>



<h2><strong>Solution: List + Middle Iterator</strong></h2>



<p>Time complexity: O(1) per op<br>Space complexity: O(n) in total</p>



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

<pre class="crayon-plain-tag">// Author: Huahua
class FrontMiddleBackQueue {
public:
  FrontMiddleBackQueue() {}

  void pushFront(int val) {
    q_.push_front(val); 
    updateMit(even() ? -1 : 0);
  }

  void pushMiddle(int val) {    
    if (q_.empty())
      q_.push_back(val);
    else
      q_.insert(even() ? next(mit_) : mit_, val);
    updateMit(even() ? -1 : 1);
  }

  void pushBack(int val) {    
    q_.push_back(val); 
    updateMit(even() ? 0 : 1);
  }

  int popFront() {     
    if (q_.empty()) return -1;
    int val = q_.front();
    q_.pop_front();
    updateMit(even() ? 0 : 1);
    return val;
  }

  int popMiddle() {    
    if (q_.empty()) return -1;
    int val = *mit_;
    mit_ = q_.erase(mit_);
    updateMit(even() ? -1 : 0);
    return val;
  }

  int popBack() {    
    if (q_.empty()) return -1;
    int val = q_.back();
    q_.pop_back();
    updateMit(even() ? -1 : 0);
    return val;
  }
private:  
  void updateMit(int delta) {
    if (q_.size() &lt;= 1) {      
      mit_ = begin(q_);
    } else {
      if (delta &gt; 0) ++mit_;
      if (delta &lt; 0) --mit_;
    }    
  }
  
  bool even() const { return q_.size() % 2 == 0; }
  
  list&lt;int&gt; q_;
  list&lt;int&gt;::iterator mit_;
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/list/leetcode-1670-design-front-middle-back-queue/">花花酱 LeetCode 1670. Design Front Middle Back Queue</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/list/leetcode-1670-design-front-middle-back-queue/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1656. Design an Ordered Stream</title>
		<link>https://zxi.mytechroad.com/blog/data-structure/leetcode-1656-design-an-ordered-stream/</link>
					<comments>https://zxi.mytechroad.com/blog/data-structure/leetcode-1656-design-an-ordered-stream/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 15 Nov 2020 04:16:02 +0000</pubDate>
				<category><![CDATA[Data Structure]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[data structure]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[easy]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7666</guid>

					<description><![CDATA[<p>There are&#160;n&#160;(id, value)&#160;pairs, where&#160;id&#160;is an integer between&#160;1&#160;and&#160;n&#160;and&#160;value&#160;is a string. No two pairs have the same&#160;id. Design a stream that takes the&#160;n&#160;pairs in an&#160;arbitrary&#160;order, and returns&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/data-structure/leetcode-1656-design-an-ordered-stream/">花花酱 LeetCode 1656. Design an Ordered Stream</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>There are&nbsp;<code>n</code>&nbsp;<code>(id, value)</code>&nbsp;pairs, where&nbsp;<code>id</code>&nbsp;is an integer between&nbsp;<code>1</code>&nbsp;and&nbsp;<code>n</code>&nbsp;and&nbsp;<code>value</code>&nbsp;is a string. No two pairs have the same&nbsp;<code>id</code>.</p>



<p>Design a stream that takes the&nbsp;<code>n</code>&nbsp;pairs in an&nbsp;<strong>arbitrary</strong>&nbsp;order, and returns the values over several calls in&nbsp;<strong>increasing order of their ids</strong>.</p>



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



<ul><li><code>OrderedStream(int n)</code>&nbsp;Constructs the stream to take&nbsp;<code>n</code>&nbsp;values and sets a current&nbsp;<code>ptr</code>&nbsp;to&nbsp;<code>1</code>.</li><li><code>String[] insert(int id, String value)</code>&nbsp;Stores the new&nbsp;<code>(id, value)</code>&nbsp;pair in the stream. After storing the pair:<ul><li>If the stream has stored a pair with&nbsp;<code>id = ptr</code>, then find the&nbsp;<strong>longest contiguous incrementing sequence</strong>&nbsp;of ids starting with&nbsp;<code>id = ptr</code>&nbsp;and return a list of the values associated with those ids&nbsp;<strong>in order</strong>. Then, update&nbsp;<code>ptr</code>&nbsp;to the last&nbsp;<code>id + 1</code>.</li><li>Otherwise, return an empty list.</li></ul></li></ul>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2020/11/10/q1.gif" alt=""/></figure>



<pre class="wp-block-preformatted wp-block-preformatted;crayon:false"><strong>Input</strong>
["OrderedStream", "insert", "insert", "insert", "insert", "insert"]
[[5], [3, "ccccc"], [1, "aaaaa"], [2, "bbbbb"], [5, "eeeee"], [4, "ddddd"]]
<strong>Output</strong>
[null, [], ["aaaaa"], ["bbbbb", "ccccc"], [], ["ddddd", "eeeee"]]
<strong>Explanation</strong>
OrderedStream os= new OrderedStream(5);
os.insert(3, "ccccc"); // Inserts (3, "ccccc"), returns [].
os.insert(1, "aaaaa"); // Inserts (1, "aaaaa"), returns ["aaaaa"].
os.insert(2, "bbbbb"); // Inserts (2, "bbbbb"), returns ["bbbbb", "ccccc"].
os.insert(5, "eeeee"); // Inserts (5, "eeeee"), returns [].
os.insert(4, "ddddd"); // Inserts (4, "ddddd"), returns ["ddddd", "eeeee"].
</pre>



<h2><strong>Solution: Straight Forward</strong></h2>



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



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

<pre class="crayon-plain-tag">// Author: Huahua
class OrderedStream {
public:
  OrderedStream(int n): data_(n + 1) {}

  vector&lt;string&gt; insert(int id, string value) {
    data_[id] = value;
    vector&lt;string&gt; ans;
    if (ptr_ == id)
      while (ptr_ &lt; data_.size() &amp;&amp; !data_[ptr_].empty())
        ans.push_back(data_[ptr_++]);
    return ans;
  }
private:
  int ptr_ = 1;
  vector&lt;string&gt; data_;
};</pre>

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

<pre class="crayon-plain-tag"># Author: Huahua
class OrderedStream:
  def __init__(self, n: int):
    self.data = [None] * (n + 1)
    self.ptr = 1

  def insert(self, id: int, value: str) -&gt; List[str]:
    self.data[id] = value
    if id == self.ptr:
      while self.ptr &lt; len(self.data) and self.data[self.ptr]:
        self.ptr += 1
      return self.data[id:self.ptr]
    return []</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/data-structure/leetcode-1656-design-an-ordered-stream/">花花酱 LeetCode 1656. Design an Ordered Stream</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/data-structure/leetcode-1656-design-an-ordered-stream/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1206. Design Skiplist</title>
		<link>https://zxi.mytechroad.com/blog/desgin/leetcode-1206-design-skiplist/</link>
					<comments>https://zxi.mytechroad.com/blog/desgin/leetcode-1206-design-skiplist/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Fri, 06 Nov 2020 21:19:24 +0000</pubDate>
				<category><![CDATA[Desgin]]></category>
		<category><![CDATA[data structure]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[skiplist]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7606</guid>

					<description><![CDATA[<p>Design a Skiplist without using any built-in libraries. A Skiplist is a data structure that takes&#160;O(log(n)) time&#160;to&#160;add,&#160;erase&#160;and&#160;search. Comparing with treap and red-black tree which has&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/desgin/leetcode-1206-design-skiplist/">花花酱 LeetCode 1206. Design Skiplist</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="花花酱 LeetCode 1206. Design Skiplist - 刷题找工作 EP367" width="500" height="281" src="https://www.youtube.com/embed/783qX31AN08?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div></figure>



<p>Design a Skiplist without using any built-in libraries.</p>



<p><em>A Skiplist is a data structure that takes&nbsp;O(log(n)) time&nbsp;to&nbsp;<code>add</code>,&nbsp;<code>erase</code>&nbsp;and&nbsp;<code>search</code>. Comparing with treap and red-black tree which has the same function and performance, the code length of Skiplist can be&nbsp;comparatively short and the idea behind Skiplists are just simple linked lists.</em></p>



<p><em>For example:&nbsp;we have a Skiplist containing&nbsp;<code>[30,40,50,60,70,90]</code>&nbsp;and we want to add&nbsp;<code>80</code>&nbsp;and&nbsp;<code>45</code>&nbsp;into it. The&nbsp;Skiplist works this way:</em></p>



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2019/09/27/1506_skiplist.gif" alt=""/></figure>



<p><br>Artyom Kalinin [CC BY-SA 3.0], via&nbsp;<a href="https://commons.wikimedia.org/wiki/File:Skip_list_add_element-en.gif" target="_blank" rel="noreferrer noopener">Wikimedia Commons</a></p>



<p><em>You can see there are many layers in the Skiplist. Each layer is a sorted linked list. With the help of the top layers,&nbsp;<code>add</code>&nbsp;,&nbsp;<code>erase</code>&nbsp;and&nbsp;<code>search&nbsp;</code>can be faster than O(n).&nbsp;It can be proven&nbsp;that the average time complexity for each operation is O(log(n)) and space complexity is O(n).</em></p>



<p>To be specific, your design should include these functions:</p>



<ul><li><code>bool search(int target)</code>&nbsp;: Return whether&nbsp;the&nbsp;<code>target</code>&nbsp;exists in the Skiplist&nbsp;or not.</li><li><code>void add(int num)</code>:&nbsp;Insert a value into the SkipList.&nbsp;</li><li><code>bool erase(int num)</code>: Remove a value in&nbsp;the Skiplist.&nbsp;If&nbsp;<code>num</code>&nbsp;does not exist in the Skiplist, do nothing and return false. If there exists multiple&nbsp;<code>num</code>&nbsp;values, removing&nbsp;any one of them is fine.</li></ul>



<p>See more about Skiplist :&nbsp;<a href="https://en.wikipedia.org/wiki/Skip_list" target="_blank" rel="noreferrer noopener">https://en.wikipedia.org/wiki/Skip_list</a></p>



<p>Note that duplicates may exist in the Skiplist, your code needs to handle this situation.</p>



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



<pre class="crayon-plain-tag">Skiplist skiplist = new Skiplist();

skiplist.add(1);
skiplist.add(2);
skiplist.add(3);
skiplist.search(0);   // return false.
skiplist.add(4);
skiplist.search(1);   // return true.
skiplist.erase(0);    // return false, 0 is not in skiplist.
skiplist.erase(1);    // return true.
skiplist.search(1);   // return false, 1 has already been erased.</pre>



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



<ul><li><code>0 &lt;= num, target&nbsp;&lt;= 20000</code></li><li>At most&nbsp;<code>50000</code>&nbsp;calls will be made to&nbsp;<code>search</code>,&nbsp;<code>add</code>, and&nbsp;<code>erase</code>.</li></ul>



<h2><strong>Solution:</strong></h2>



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



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



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



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



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



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

<pre class="crayon-plain-tag">// Author: Huahua
class Skiplist {
public:
  Skiplist() { head_ = make_shared&lt;Node&gt;(); }

  bool search(int target) {
    for (auto node = head_; node; node = node-&gt;down) {
      while (node-&gt;next &amp;&amp; node-&gt;next-&gt;val &lt; target)
        node = node-&gt;next;
      if (node-&gt;next &amp;&amp; node-&gt;next-&gt;val == target)
        return true;
    }
    return false;
  }

  void add(int num) {
    stack&lt;shared_ptr&lt;Node&gt;&gt; s;
    shared_ptr&lt;Node&gt; down;
    bool insert = true;
    
    for (auto node = head_; node; node = node-&gt;down) {
      while (node-&gt;next &amp;&amp; node-&gt;next-&gt;val &lt; num)
        node = node-&gt;next;
      s.push(node);
    }
    
    while (!s.empty() &amp;&amp; insert) {
      auto cur = s.top(); s.pop();
      cur-&gt;next = make_shared&lt;Node&gt;(num, cur-&gt;next, down);
      down = cur-&gt;next;
      insert = rand() &amp; 1; // 50% chance
    }
    
    if (insert) // create a new layer.
      head_ = make_shared&lt;Node&gt;(-1, nullptr, head_);
  }

  bool erase(int num) {
    bool found = false;
    for (auto node = head_; node; node = node-&gt;down) {
      while (node-&gt;next &amp;&amp; node-&gt;next-&gt;val &lt; num)
        node = node-&gt;next;
      if (node-&gt;next &amp;&amp; node-&gt;next-&gt;val == num) {
        found = true;
        node-&gt;next = node-&gt;next-&gt;next;
      }
    }
    return found;
  }
private:
  struct Node {
    Node(int val = -1, 
         shared_ptr&lt;Node&gt; next = nullptr, 
         shared_ptr&lt;Node&gt; down = nullptr): 
          val(val), next(next), down(down) {}
    int val;
    shared_ptr&lt;Node&gt; next;
    shared_ptr&lt;Node&gt; down;
  };
  
  shared_ptr&lt;Node&gt; head_;
};

/**
 * Your Skiplist object will be instantiated and called as such:
 * Skiplist* obj = new Skiplist();
 * bool param_1 = obj-&gt;search(target);
 * obj-&gt;add(num);
 * bool param_3 = obj-&gt;erase(num);
 */</pre>

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

<pre class="crayon-plain-tag">import random

class Node:
  def __init__(self, val=-1, right=None, down=None):
    self.val = val
    self.right = right
    self.down = down
    
class Skiplist:
  def __init__(self):
    self.head = Node() # Dummy head

  def search(self, target: int) -&gt; bool:
    node = self.head
    while node:
      # Move to the right in the current level
      while node.right and node.right.val &lt; target:
        node = node.right
      if node.right and node.right.val == target:
        return True
      # Move to the the next level
      node = node.down
    return False

  def add(self, num: int) -&gt; None:
    nodes = []
    node = self.head
    while node:
      # Move to the right in the current level
      while node.right and node.right.val &lt; num:
        node = node.right
      nodes.append(node)
      # Move to the next level
      node = node.down
    
    insert = True
    down = None
    while insert and nodes:
      node = nodes.pop()
      node.right = Node(num, node.right, down)
      down = node.right
      insert = (random.getrandbits(1) == 0)      
    
    # Create a new level with a dummy head.
    # right = None
    # down = current head
    if insert:
      self.head = Node(-1, None, self.head)

  def erase(self, num: int) -&gt; bool:
    node = self.head
    found = False
    while node:
      # Move to the right in the current level
      while node.right and node.right.val &lt; num:
        node = node.right
      # Find the target node
      if node.right and node.right.val == num:
        # Delete by skipping
        node.right = node.right.right
        found = True
      # Move to the next level
      node = node.down      
    return found
        
# Your Skiplist object will be instantiated and called as such:
# obj = Skiplist()
# param_1 = obj.search(target)
# obj.add(num)
# param_3 = obj.erase(num)</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/desgin/leetcode-1206-design-skiplist/">花花酱 LeetCode 1206. Design Skiplist</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/desgin/leetcode-1206-design-skiplist/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1381. Design a Stack With Increment Operation</title>
		<link>https://zxi.mytechroad.com/blog/stack/leetcode-1381-design-a-stack-with-increment-operation/</link>
					<comments>https://zxi.mytechroad.com/blog/stack/leetcode-1381-design-a-stack-with-increment-operation/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 15 Mar 2020 08:30:22 +0000</pubDate>
				<category><![CDATA[Stack]]></category>
		<category><![CDATA[data structure]]></category>
		<category><![CDATA[desgin]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[stack]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=6497</guid>

					<description><![CDATA[<p>Design a stack which supports the following operations. Implement the&#160;CustomStack&#160;class: CustomStack(int maxSize)&#160;Initializes the object with&#160;maxSize&#160;which is the maximum number of elements in the stack or&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/stack/leetcode-1381-design-a-stack-with-increment-operation/">花花酱 LeetCode 1381. Design a Stack With Increment Operation</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Design a stack which supports the following operations.</p>



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



<ul><li><code>CustomStack(int maxSize)</code>&nbsp;Initializes the object with&nbsp;<code>maxSize</code>&nbsp;which is the maximum number of elements in the stack or do nothing if the stack reached the&nbsp;<code>maxSize</code>.</li><li><code>void push(int x)</code>&nbsp;Adds&nbsp;<code>x</code>&nbsp;to the top of the stack if the stack hasn&#8217;t reached the&nbsp;<code>maxSize</code>.</li><li><code>int pop()</code>&nbsp;Pops and returns the top of stack or&nbsp;<strong>-1</strong>&nbsp;if the stack is empty.</li><li><code>void inc(int k, int val)</code>&nbsp;Increments the bottom&nbsp;<code>k</code>&nbsp;elements of the stack by&nbsp;<code>val</code>. If there are less than&nbsp;<code>k</code>&nbsp;elements in the stack, just increment all the elements in the stack.</li></ul>



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



<pre class="wp-block-preformatted wp-block-preformatted;crayon:false"><strong>Input</strong>
["CustomStack","push","push","pop","push","push","push","increment","increment","pop","pop","pop","pop"]
[[3],[1],[2],[],[2],[3],[4],[5,100],[2,100],[],[],[],[]]
<strong>Output</strong>
[null,null,null,2,null,null,null,null,null,103,202,201,-1]
<strong>Explanation</strong>
CustomStack customStack = new CustomStack(3); // Stack is Empty []
customStack.push(1);                          // stack becomes [1]
customStack.push(2);                          // stack becomes [1, 2]
customStack.pop();                            // return 2 --&gt; Return top of the stack 2, stack becomes [1]
customStack.push(2);                          // stack becomes [1, 2]
customStack.push(3);                          // stack becomes [1, 2, 3]
customStack.push(4);                          // stack still [1, 2, 3], Don't add another elements as size is 4
customStack.increment(5, 100);                // stack becomes [101, 102, 103]
customStack.increment(2, 100);                // stack becomes [201, 202, 103]
customStack.pop();                            // return 103 --&gt; Return top of the stack 103, stack becomes [201, 202]
customStack.pop();                            // return 202 --&gt; Return top of the stack 102, stack becomes [201]
customStack.pop();                            // return 201 --&gt; Return top of the stack 101, stack becomes []
customStack.pop();                            // return -1 --&gt; Stack is empty return -1.
</pre>



<h2><strong>Solution: Simulation</strong></h2>



<p>Time complexity: <br>init: O(1)<br>pop: O(1)<br>push: O(1)<br>inc: O(k)</p>



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

<pre class="crayon-plain-tag">// Author: Huahua
class CustomStack {
public:
  CustomStack(int maxSize): max_size_(maxSize) {}

  void push(int x) {
    if (data_.size() == max_size_) return;
    data_.push_back(x);
  }

  int pop() {
    if (data_.empty()) return -1;
    int val = data_.back();
    data_.pop_back();
    return val;
  }

  void increment(int k, int val) {
    for (int i = 0; i &lt; min(static_cast&lt;size_t&gt;(k), 
                            data_.size()); ++i)
      data_[i] += val;
  }
private:
  int max_size_;
  vector&lt;int&gt; data_;
};

/**
 * Your CustomStack object will be instantiated and called as such:
 * CustomStack* obj = new CustomStack(maxSize);
 * obj-&gt;push(x);
 * int param_2 = obj-&gt;pop();
 * obj-&gt;increment(k,val);
 */</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/stack/leetcode-1381-design-a-stack-with-increment-operation/">花花酱 LeetCode 1381. Design a Stack With Increment Operation</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/stack/leetcode-1381-design-a-stack-with-increment-operation/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1172. Dinner Plate Stacks</title>
		<link>https://zxi.mytechroad.com/blog/stack/leetcode-1172-dinner-plate-stacks/</link>
					<comments>https://zxi.mytechroad.com/blog/stack/leetcode-1172-dinner-plate-stacks/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 25 Aug 2019 05:59:35 +0000</pubDate>
				<category><![CDATA[Stack]]></category>
		<category><![CDATA[data structure]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[stack]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=5490</guid>

					<description><![CDATA[<p>You have an infinite number of stacks arranged in a row and numbered (left to right) from 0, each of the stacks has the same&#160;maximum&#160;capacity.&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/stack/leetcode-1172-dinner-plate-stacks/">花花酱 LeetCode 1172. Dinner Plate Stacks</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-4-3 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe width="500" height="375" src="https://www.youtube.com/embed/DUsOp0HMQQg?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div></figure>



<p>You have an infinite number of stacks arranged in a row and numbered (left to right) from 0, each of the stacks has the same&nbsp;maximum&nbsp;<code>capacity</code>.</p>



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



<ul><li><code>DinnerPlates(int capacity)</code>&nbsp;Initializes the object with the maximum&nbsp;<code>capacity</code>&nbsp;of the stacks.</li><li><code>void push(int val)</code>&nbsp;pushes the given positive integer&nbsp;<code>val</code>&nbsp;into the leftmost stack with size less than&nbsp;<code>capacity</code>.</li><li><code>int pop()</code>&nbsp;returns the value at the top of the rightmost non-empty stack and removes it from that stack, and returns&nbsp;<code>-1</code>&nbsp;if all stacks are empty.</li><li><code>int popAtStack(int index)</code>&nbsp;returns the value at the top of the stack with the given&nbsp;<code>index</code>&nbsp;and removes it from that stack, and returns -1 if the stack with that&nbsp;given&nbsp;<code>index</code>&nbsp;is empty.</li></ul>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input: </strong>
["DinnerPlates","push","push","push","push","push","popAtStack","push","push","popAtStack","popAtStack","pop","pop","pop","pop","pop"]
[[2],[1],[2],[3],[4],[5],[0],[20],[21],[0],[2],[],[],[],[],[]]
<strong>Output: </strong>
</pre>


<p>[null,null,null,null,null,null,2,null,null,20,21,5,4,3,1,-1]</p>



<pre class="wp-block-preformatted;crayon:false">
<p><strong>Explanation: </strong>
DinnerPlates D = DinnerPlates(2);  // Initialize with capacity = 2
D.push(1);
D.push(2);
D.push(3);
D.push(4);
D.push(5);         // The stacks are now:  2 &nbsp;4
&nbsp;                                          1 &nbsp;3 &nbsp;5
                                           ﹈ ﹈ ﹈
D.popAtStack(0);   // Returns 2.  The stacks are now:    &nbsp;4
            &nbsp;                                          1 &nbsp;3 &nbsp;5
                                                       ﹈ ﹈ ﹈
D.push(20);        // The stacks are now: 20  4
&nbsp;                                          1 &nbsp;3 &nbsp;5
                                           ﹈ ﹈ ﹈
D.push(21);        // The stacks are now: 20  4 21
&nbsp;                                          1 &nbsp;3 &nbsp;5
                                           ﹈ ﹈ ﹈
D.popAtStack(0);   // Returns 20.  The stacks are now:     4 21
             &nbsp;                                          1 &nbsp;3 &nbsp;5
                                                        ﹈ ﹈ ﹈
D.popAtStack(2);   // Returns 21.  The stacks are now:     4
             &nbsp;                                          1 &nbsp;3 &nbsp;5
                                                        ﹈ ﹈ ﹈ 
D.pop()            // Returns 5.  The stacks are now:      4
             &nbsp;                                          1 &nbsp;3 
                                                        ﹈ ﹈  
D.pop()            // Returns 4.  The stacks are now:   1 &nbsp;3 
                                                        ﹈ ﹈   
D.pop()            // Returns 3.  The stacks are now:   1 
                                                        ﹈   
D.pop()            // Returns 1.  There are no stacks.
D.pop()            // Returns -1.  There are still no stacks.
</p>
</pre>



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



<ul><li><code>1 &lt;= capacity&nbsp;&lt;= 20000</code></li><li><code>1 &lt;= val&nbsp;&lt;= 20000</code></li><li><code>0 &lt;= index&nbsp;&lt;= 100000</code></li><li>At most&nbsp;<code>200000</code>&nbsp;calls will be made to&nbsp;<code>push</code>,&nbsp;<code>pop</code>, and&nbsp;<code>popAtStack</code>.</li></ul>



<h2><strong>Solution: Array of stacks + TreeSet</strong></h2>



<p>Store all the stacks in an array, and store the indices of all free stacks in a tree set.<br>1. push(): find the first free stack and push onto it, if it becomes full, remove it from free set.<br>2. pop(): pop element from the last stack by calling popAtIndex(stacks.size()-1).<br>3. popAtIndex(): pop element from given index<br>  3.1 add it to free set if it was full <br>  3.2 remove it from free set if it becomes empty <br>     3.2.1 remove it from stack array if it is the last stack</p>



<p>Time complexity:  <br>Push: O(logn)<br>Pop: O(logn)<br>PopAtIndex: O(logn)</p>



<p>Space complexity:  O(n) </p>



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

<pre class="crayon-plain-tag">// Author: Huahua
class DinnerPlates {
public:
  DinnerPlates(int capacity): cap_(capacity) {}

  void push(int val) {  
    int index = aval_.empty() ? stacks_.size() : *begin(aval_);
    if (index == stacks_.size()) stacks_.emplace_back();
    stack&lt;int&gt;&amp; s = stacks_[index];
    s.push(val);
    if (s.size() == cap_)
      aval_.erase(index);
    else if (s.size() == 1) // only insert for the first element
      aval_.insert(index);
  }

  int pop() { return popAtStack(stacks_.size() - 1); }

  int popAtStack(int index) {
    if (index &lt; 0 || index &gt;= stacks_.size() || stacks_[index].empty()) return -1;
    stack&lt;int&gt;&amp; s = stacks_[index];
    int val = s.top(); s.pop();
    if (s.size() == cap_ - 1) aval_.insert(index);    
    
    // Amortized O(1)
    auto it = prev(end(aval_));
    while (stacks_.size() &amp;&amp; stacks_.back().empty()) {
      stacks_.pop_back();
      aval_.erase(it--);
    }
    return val;
  }
private:
  int cap_;
  set&lt;int&gt; aval_;
  vector&lt;stack&lt;int&gt;&gt; stacks_;
};</pre>
</div></div>



<p></p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/stack/leetcode-1172-dinner-plate-stacks/">花花酱 LeetCode 1172. Dinner Plate Stacks</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/stack/leetcode-1172-dinner-plate-stacks/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 622. Design Circular Queue</title>
		<link>https://zxi.mytechroad.com/blog/desgin/leetcode-622-design-circular-queue/</link>
					<comments>https://zxi.mytechroad.com/blog/desgin/leetcode-622-design-circular-queue/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Fri, 13 Jul 2018 05:37:46 +0000</pubDate>
				<category><![CDATA[Desgin]]></category>
		<category><![CDATA[data structure]]></category>
		<category><![CDATA[deque]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[queue]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=3104</guid>

					<description><![CDATA[<p>Design your implementation of the circular queue. The circular queue is a linear data structure in which the operations are performed based on FIFO (First&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/desgin/leetcode-622-design-circular-queue/">花花酱 LeetCode 622. Design Circular Queue</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Design your implementation of the circular queue. The circular queue is a linear data structure in which the operations are performed based on FIFO (First In First Out) principle and the last position is connected back to the first position to make a circle. It is also called &#8220;Ring Buffer&#8221;.</p>



<p>One of the benefits of the circular queue is that we can make use of the spaces in front of the queue. In a normal queue, once the queue becomes full, we cannot insert the next element even if there is a space in front of the queue. But using the circular queue, we can use the space to store new values.</p>



<p>Your implementation should support following operations:</p>



<ul><li><code>MyCircularQueue(k)</code>: Constructor, set the size of the queue to be k.</li><li><code>Front</code>: Get the front item from the queue. If the queue is empty, return -1.</li><li><code>Rear</code>: Get the last item from the queue. If the queue is empty, return -1.</li><li><code>enQueue(value)</code>: Insert an element into the circular queue. Return true if the operation is successful.</li><li><code>deQueue()</code>: Delete an element from the circular queue. Return true if the operation is successful.</li><li><code>isEmpty()</code>: Checks whether the circular queue is empty or not.</li><li><code>isFull()</code>: Checks whether the circular queue is full or not.</li></ul>



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



<pre class="wp-block-preformatted;crayon:false">MyCircularQueue circularQueue = new MyCircularQueue(3); // set the size to be 3
circularQueue.enQueue(1); &nbsp;// return true
circularQueue.enQueue(2); &nbsp;// return true
circularQueue.enQueue(3); &nbsp;// return true
circularQueue.enQueue(4); &nbsp;// return false, the queue is full
circularQueue.Rear(); &nbsp;// return 3
circularQueue.isFull(); &nbsp;// return true
circularQueue.deQueue(); &nbsp;// return true
circularQueue.enQueue(4); &nbsp;// return true
circularQueue.Rear(); &nbsp;// return 4
</pre>



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



<ul><li>All values will be in the range of [0, 1000].</li><li>The number of operations will be in the range of&nbsp;[1, 1000].</li><li>Please do not use the built-in Queue library.</li></ul>



<h2><strong>Solution: Simulate with an array</strong></h2>



<p>We need a fixed length array, and the head location as well as the size of the current queue.</p>



<p>We can use q[head] to access the front, and q[(head + size &#8211; 1) % k] to access the rear.</p>



<p>Time complexity: O(1) for all the operations.<br>Space complexity: O(k)</p>



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

<pre class="crayon-plain-tag">// Author: Huahua
class MyCircularQueue {
public:
  MyCircularQueue(int k): q_(k) {}
  
  bool enQueue(int value) {
    if (isFull()) return false;
    q_[(head_ + size_) % q_.size()] = value;    
    ++size_;
    return true;
  }
  
  bool deQueue() {
    if (isEmpty()) return false;
    head_ = (head_ + 1) % q_.size();
    --size_;
    return true;
  }

  int Front() { return isEmpty() ? -1 : q_[head_]; }

  int Rear() { return isEmpty() ? -1 : q_[(head_ + size_ - 1) % q_.size()]; }

  bool isEmpty() { return size_ == 0; }

  bool isFull() { return size_ == q_.size(); }
private:
  vector&lt;int&gt; q_;
  int head_ = 0;
  int size_ = 0;
};</pre>

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

<pre class="crayon-plain-tag">class MyCircularQueue {
  private int[] q;
  private int head;
  private int size;
  
  public MyCircularQueue(int k) {
    this.q = new int[k];
    this.head = 0;
    this.size = 0;
  }
  
  public boolean enQueue(int value) {
    if (this.isFull()) return false;    
    this.q[(this.head + this.size) % this.q.length] = value;
    ++this.size;
    return true;
  }

  public boolean deQueue() {
    if (this.isEmpty()) return false;
    this.head = (this.head + 1) % this.q.length;
    --this.size;
    return true;
  }

  public int Front() {
    return this.isEmpty() ? -1 : this.q[this.head];
  }

  public int Rear() {
    return this.isEmpty() ? -1 : this.q[(this.head + this.size - 1) % this.q.length];
  }

  public boolean isEmpty() { return this.size == 0; }  

  public boolean isFull() { return this.size == this.q.length; }
}</pre>

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

<pre class="crayon-plain-tag">class MyCircularQueue:
  def __init__(self, k: int):
    self.q = [0] * k
    self.k = k
    self.head = self.size = 0


  def enQueue(self, value: int) -&gt; bool:
    if self.isFull(): return False
    self.q[(self.head + self.size) % self.k] = value
    self.size += 1
    return True


  def deQueue(self) -&gt; bool:
    if self.isEmpty(): return False
    self.head = (self.head + 1) % self.k
    self.size -= 1
    return True


  def Front(self) -&gt; int:
    return -1 if self.isEmpty() else self.q[self.head]


  def Rear(self) -&gt; int:
    return -1 if self.isEmpty() else self.q[(self.head + self.size - 1) % self.k]


  def isEmpty(self) -&gt; bool:
    return self.size == 0


  def isFull(self) -&gt; bool:
    return self.size == self.k</pre>
</div></div>



<p></p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/desgin/leetcode-622-design-circular-queue/">花花酱 LeetCode 622. Design Circular Queue</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/desgin/leetcode-622-design-circular-queue/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 432. All O`one Data Structure</title>
		<link>https://zxi.mytechroad.com/blog/data-structure/leetcode-432-all-oone-data-structure/</link>
					<comments>https://zxi.mytechroad.com/blog/data-structure/leetcode-432-all-oone-data-structure/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 07 Apr 2018 04:44:37 +0000</pubDate>
				<category><![CDATA[Data Structure]]></category>
		<category><![CDATA[Hashtable]]></category>
		<category><![CDATA[List]]></category>
		<category><![CDATA[data structure]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[O(1)]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=2434</guid>

					<description><![CDATA[<p>Problem 题目大意：设计一种数据结构，支持inc/dec/getmaxkey/getminkey操作，必须都在O(1)时间内完成。 https://leetcode.com/problems/all-oone-data-structure/description/ Implement a data structure supporting the following operations: Inc(Key) &#8211; Inserts a new key with value 1. Or increments an existing key by&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/data-structure/leetcode-432-all-oone-data-structure/">花花酱 LeetCode 432. All O`one Data Structure</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><iframe width="500" height="375" src="https://www.youtube.com/embed/wYqLisoH80w?feature=oembed" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></p>
<h1>Problem</h1>
<p>题目大意：设计一种数据结构，支持inc/dec/getmaxkey/getminkey操作，必须都在O(1)时间内完成。</p>
<p><a href="https://leetcode.com/problems/all-oone-data-structure/description/">https://leetcode.com/problems/all-oone-data-structure/description/</a></p>
<div class="question-description">
<div>
<p>Implement a data structure supporting the following operations:</p>
<ol>
<li>Inc(Key) &#8211; Inserts a new key with value 1. Or increments an existing key by 1. Key is guaranteed to be a <b>non-empty</b> string.</li>
<li>Dec(Key) &#8211; If Key&#8217;s value is 1, remove it from the data structure. Otherwise decrements an existing key by 1. If the key does not exist, this function does nothing. Key is guaranteed to be a <b>non-empty</b> string.</li>
<li>GetMaxKey() &#8211; Returns one of the keys with maximal value. If no element exists, return an empty string <code>""</code>.</li>
<li>GetMinKey() &#8211; Returns one of the keys with minimal value. If no element exists, return an empty string <code>""</code>.</li>
</ol>
<p>Challenge: Perform all these in O(1) time complexity.</p>
</div>
<p><img class="alignnone size-full wp-image-2439" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2018/04/432-ep178.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/04/432-ep178.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/04/432-ep178-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/04/432-ep178-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
</div>
<h1><strong>Solution</strong></h1>
<p>Time complexity: O(1)</p>
<p>Space complexity: O(n), n = # of unique keys</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 32 ms
class AllOne {
public:
  /** Initialize your data structure here. */
  AllOne() {}

  /** Inserts a new key &lt;Key&gt; with value 1. Or increments an existing key by 1. */
  void inc(string key) {
    auto it = m_.find(key);
    
    if (it == m_.end()) {
      if (l_.empty() || l_.front().value != 1) 
        l_.push_front({1, {key}});
      else
        l_.front().keys.insert(key);
      m_[key] = l_.begin();
      return;
    }
    
    auto lit = it-&gt;second;
    
    auto nit = next(lit);
    if (nit == l_.end() || nit-&gt;value != lit-&gt;value + 1)
      nit = l_.insert(nit, {lit-&gt;value + 1, {}});
    nit-&gt;keys.insert(key);
    m_[key] = nit;
    
    remove(lit, key);
  }

  /** Decrements an existing key by 1. If Key's value is 1, remove it from the data structure. */
  void dec(string key) {
    auto it = m_.find(key);
    if (it == m_.end()) return;
    
    auto lit = it-&gt;second;
        
    if (lit-&gt;value &gt; 1) {
      auto pit = prev(lit);
      if (lit == l_.begin() || pit-&gt;value != lit-&gt;value - 1)
        pit = l_.insert(lit, {lit-&gt;value - 1, {}});
      pit-&gt;keys.insert(key);
      m_[key] = pit;
    } else {
      // value == 1, remove from the data structure
      m_.erase(key);
    }
    
    remove(lit, key);    
  }

  /** Returns one of the keys with maximal value. */
  string getMaxKey() {
    return l_.empty() ? "" : *l_.back().keys.cbegin();
  }

  /** Returns one of the keys with Minimal value. */
  string getMinKey() {
    return l_.empty() ? "" : *l_.front().keys.cbegin();
  }
private:
  struct Node {  
    int value;
    unordered_set&lt;string&gt; keys;
  };
  
  list&lt;Node&gt; l_;
  unordered_map&lt;string, list&lt;Node&gt;::iterator&gt; m_;
  
  // Remove from old node.
  void remove(list&lt;Node&gt;::iterator it, const string&amp; key) {
    it-&gt;keys.erase(key);
    if (it-&gt;keys.empty())
      l_.erase(it);
  }
};</pre><p></p>
<h1><strong>Related Problems</strong></h1>
<ul>
<li><a href="http://zxi.mytechroad.com/blog/hashtable/leetcode-460-lfu-cache/">[解题报告] LeetCode 460. LFU Cache 花花酱</a></li>
<li><a href="http://zxi.mytechroad.com/blog/hashtable/leetcode-146-lru-cache/">[解题报告] LeetCode 146. LRU Cache O(1)</a></li>
<li><a href="http://zxi.mytechroad.com/blog/hashtable/leetcode-380-insert-delete-getrandom-o1/">[解题报告] LeetCode 380. Insert Delete GetRandom O(1)</a></li>
<li><a href="http://zxi.mytechroad.com/blog/hashtable/leetcode-381-insert-delete-getrandom-o1-duplicates-allowed/">[解题报告] LeetCode 381. Insert Delete GetRandom O(1) &amp;#8211; Duplicates allowed</a></li>
</ul>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/data-structure/leetcode-432-all-oone-data-structure/">花花酱 LeetCode 432. All O`one Data Structure</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/data-structure/leetcode-432-all-oone-data-structure/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
