<?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>Desgin &#8211; Huahua&#8217;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/category/desgin/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog</link>
	<description></description>
	<lastBuildDate>Sun, 30 Mar 2025 15:17:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.7.2</generator>

<image>
	<url>https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/cropped-photo-32x32.jpg</url>
	<title>Desgin &#8211; Huahua&#8217;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>花花酱 LeetCode 2349. Design a Number Container System</title>
		<link>https://zxi.mytechroad.com/blog/desgin/leetcode-2349-design-a-number-container-system/</link>
					<comments>https://zxi.mytechroad.com/blog/desgin/leetcode-2349-design-a-number-container-system/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 30 Mar 2025 15:16:49 +0000</pubDate>
				<category><![CDATA[Desgin]]></category>
		<category><![CDATA[hashtable]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[treeset]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=10244</guid>

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



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



<pre class="urvanov-syntax-highlighter-plain-tag">class NumberContainers {
public:
  NumberContainers() {}
  
  void change(int index, int number) {
    if (m_.count(index)) {
      auto it = idx_.find(m_[index]);
      it-&gt;second.erase(index);
      if (it-&gt;second.empty())
        idx_.erase(it);
    }
    m_[index] = number;
    idx_[number].insert(index);
  }
  
  int find(int number) {
    auto it = idx_.find(number);
    if (it == end(idx_)) return -1;
    return *begin(it-&gt;second);
  }
private:
  unordered_map&lt;int, int&gt; m_; // index -&gt; num
  unordered_map&lt;int, set&lt;int&gt;&gt; idx_; // num -&gt; {index}
};</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/desgin/leetcode-2349-design-a-number-container-system/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2241. Design an ATM Machine</title>
		<link>https://zxi.mytechroad.com/blog/desgin/leetcode-2241-design-an-atm-machine/</link>
					<comments>https://zxi.mytechroad.com/blog/desgin/leetcode-2241-design-an-atm-machine/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 17 Apr 2022 05:46:46 +0000</pubDate>
				<category><![CDATA[Desgin]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[medium]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9659</guid>

					<description><![CDATA[There is an ATM machine that stores banknotes of&#160;5&#160;denominations:&#160;20,&#160;50,&#160;100,&#160;200, and&#160;500&#160;dollars. Initially the ATM is empty. The user can use the machine to deposit or withdraw&#8230;]]></description>
										<content:encoded><![CDATA[
<p>There is an ATM machine that stores banknotes of&nbsp;<code>5</code>&nbsp;denominations:&nbsp;<code>20</code>,&nbsp;<code>50</code>,&nbsp;<code>100</code>,&nbsp;<code>200</code>, and&nbsp;<code>500</code>&nbsp;dollars. Initially the ATM is empty. The user can use the machine to deposit or withdraw any amount of money.</p>



<p>When withdrawing, the machine prioritizes using banknotes of&nbsp;<strong>larger</strong>&nbsp;values.</p>



<ul class="wp-block-list"><li>For example, if you want to withdraw&nbsp;<code>$300</code>&nbsp;and there are&nbsp;<code>2</code>&nbsp;<code>$50</code>&nbsp;banknotes,&nbsp;<code>1</code>&nbsp;<code>$100</code>&nbsp;banknote, and&nbsp;<code>1</code>&nbsp;<code>$200</code>&nbsp;banknote, then the machine will use the&nbsp;<code>$100</code>&nbsp;and&nbsp;<code>$200</code>&nbsp;banknotes.</li><li>However, if you try to withdraw&nbsp;<code>$600</code>&nbsp;and there are&nbsp;<code>3</code>&nbsp;<code>$200</code>&nbsp;banknotes and&nbsp;<code>1</code>&nbsp;<code>$500</code>&nbsp;banknote, then the withdraw request will be rejected because the machine will first try to use the&nbsp;<code>$500</code>&nbsp;banknote and then be unable to use banknotes to complete the remaining&nbsp;<code>$100</code>. Note that the machine is&nbsp;<strong>not</strong>&nbsp;allowed to use the&nbsp;<code>$200</code>&nbsp;banknotes instead of the&nbsp;<code>$500</code>&nbsp;banknote.</li></ul>



<p>Implement the ATM class:</p>



<ul class="wp-block-list"><li><code>ATM()</code>&nbsp;Initializes the ATM object.</li><li><code>void deposit(int[] banknotesCount)</code>&nbsp;Deposits new banknotes in the order&nbsp;<code>$20</code>,&nbsp;<code>$50</code>,&nbsp;<code>$100</code>,&nbsp;<code>$200</code>, and&nbsp;<code>$500</code>.</li><li><code>int[] withdraw(int amount)</code>&nbsp;Returns an array of length&nbsp;<code>5</code>&nbsp;of the number of banknotes that will be handed to the user in the order&nbsp;<code>$20</code>,&nbsp;<code>$50</code>,&nbsp;<code>$100</code>,&nbsp;<code>$200</code>, and&nbsp;<code>$500</code>, and update the number of banknotes in the ATM after withdrawing. Returns&nbsp;<code>[-1]</code>&nbsp;if it is not possible (do&nbsp;<strong>not</strong>&nbsp;withdraw any banknotes in this case).</li></ul>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input</strong>
["ATM", "deposit", "withdraw", "deposit", "withdraw", "withdraw"]
[[], [[0,0,1,2,1]], [600], [[0,1,0,1,1]], [600], [550]]
<strong>Output</strong>
[null, null, [0,0,1,0,1], null, [-1], [0,1,0,0,1]]

<strong>Explanation</strong>
ATM atm = new ATM();
atm.deposit([0,0,1,2,1]); // Deposits 1 $100 banknote, 2 $200 banknotes,
                          // and 1 $500 banknote.
atm.withdraw(600);        // Returns [0,0,1,0,1]. The machine uses 1 $100 banknote
                          // and 1 $500 banknote. The banknotes left over in the
                          // machine are [0,0,0,2,0].
atm.deposit([0,1,0,1,1]); // Deposits 1 $50, $200, and $500 banknote.
                          // The banknotes in the machine are now [0,1,0,3,1].
atm.withdraw(600);        // Returns [-1]. The machine will try to use a $500 banknote
                          // and then be unable to complete the remaining $100,
                          // so the withdraw request will be rejected.
                          // Since the request is rejected, the number of banknotes
                          // in the machine is not modified.
atm.withdraw(550);        // Returns [0,1,0,0,1]. The machine uses 1 $50 banknote
                          // and 1 $500 banknote.</pre>



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



<ul class="wp-block-list"><li><code>banknotesCount.length == 5</code></li><li><code>0 &lt;= banknotesCount[i] &lt;= 10<sup>9</sup></code></li><li><code>1 &lt;= amount &lt;= 10<sup>9</sup></code></li><li>At most&nbsp;<code>5000</code>&nbsp;calls&nbsp;<strong>in total</strong>&nbsp;will be made to&nbsp;<code>withdraw</code>&nbsp;and&nbsp;<code>deposit</code>.</li><li>At least&nbsp;<strong>one</strong>&nbsp;call will be made to each function&nbsp;<code>withdraw</code>&nbsp;and&nbsp;<code>deposit</code>.</li></ul>



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



<p>Follow the rules. Note: total count can be very large, use long instead.</p>



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
constexpr int kNotes = 5;
constexpr long notes[kNotes] = {20, 50, 100, 200, 500};

class ATM {
public:
  ATM(): counts(kNotes) {}

  void deposit(vector&lt;int&gt; banknotesCount) {
    for (int i = 0; i &lt; kNotes; ++i)
      counts[i] += banknotesCount[i];
  }

  vector&lt;int&gt; withdraw(int amount) {
    vector&lt;int&gt; ans(kNotes);
    vector&lt;long&gt; tmp(counts);
    for (int i = kNotes - 1; i &gt;= 0; --i)
      if (amount &gt;= notes[i]) {
        int c = min(counts[i], amount / notes[i]);
        ans[i] = c;
        amount -= c * notes[i];
        tmp[i] -= c;
      }
    if (amount != 0) return {-1};
    counts.swap(tmp);
    return ans;
  }
private:
  vector&lt;long&gt; counts;  
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/desgin/leetcode-2241-design-an-atm-machine/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[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;]]></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; web-share" referrerpolicy="strict-origin-when-cross-origin" 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 decoding="async" 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 class="wp-block-list"><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="urvanov-syntax-highlighter-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 class="wp-block-list"><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 class="wp-block-heading"><strong>Solution:</strong></h2>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/11/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 decoding="async" 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 loading="lazy" decoding="async" 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="auto, (max-width: 960px) 100vw, 960px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/11/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="auto, (max-width: 960px) 100vw, 960px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/11/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="auto, (max-width: 960px) 100vw, 960px" /></figure>



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

<pre class="urvanov-syntax-highlighter-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="urvanov-syntax-highlighter-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>
]]></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 1472. Design Browser History</title>
		<link>https://zxi.mytechroad.com/blog/desgin/leetcode-1472-design-browser-history/</link>
					<comments>https://zxi.mytechroad.com/blog/desgin/leetcode-1472-design-browser-history/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 07 Jun 2020 05:51:23 +0000</pubDate>
				<category><![CDATA[Desgin]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[simulation]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=6886</guid>

					<description><![CDATA[You have a&#160;browser&#160;of one tab where you start on the&#160;homepage&#160;and you can visit another&#160;url, get back in the history number of&#160;steps&#160;or move forward in the&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You have a&nbsp;<strong>browser</strong>&nbsp;of one tab where you start on the&nbsp;<code>homepage</code>&nbsp;and you can visit another&nbsp;<code>url</code>, get back in the history number of&nbsp;<code>steps</code>&nbsp;or move forward in the history number of&nbsp;<code>steps</code>.</p>



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



<ul class="wp-block-list"><li><code>BrowserHistory(string homepage)</code>&nbsp;Initializes the object with the&nbsp;<code>homepage</code>&nbsp;of the browser.</li><li><code>void visit(string url)</code>&nbsp;visits&nbsp;<code>url</code>&nbsp;from the current page. It clears up all the forward history.</li><li><code>string back(int steps)</code>&nbsp;Move&nbsp;<code>steps</code>&nbsp;back in history. If you can only return&nbsp;<code>x</code>&nbsp;steps in the history and&nbsp;<code>steps &gt; x</code>, you will&nbsp;return only&nbsp;<code>x</code>&nbsp;steps. Return the current&nbsp;<code>url</code>&nbsp;after moving back in history&nbsp;<strong>at most</strong>&nbsp;<code>steps</code>.</li><li><code>string forward(int steps)</code>&nbsp;Move&nbsp;<code>steps</code>&nbsp;forward in history. If you can only forward&nbsp;<code>x</code>&nbsp;steps in the history and&nbsp;<code>steps &gt; x</code>, you will&nbsp;forward only&nbsp;<code>x</code>&nbsp;steps. Return the current&nbsp;<code>url</code>&nbsp;after forwarding in history&nbsp;<strong>at most</strong>&nbsp;<code>steps</code>.</li></ul>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong>
["BrowserHistory","visit","visit","visit","back","back","forward","visit","forward","back","back"]
[["leetcode.com"],["google.com"],["facebook.com"],["youtube.com"],[1],[1],[1],["linkedin.com"],[2],[2],[7]]
<strong>Output:</strong>
[null,null,null,null,"facebook.com","google.com","facebook.com",null,"linkedin.com","google.com","leetcode.com"]
<p><strong>Explanation:</strong>
BrowserHistory browserHistory = new BrowserHistory("leetcode.com");
browserHistory.visit("google.com");       // You are in "leetcode.com". Visit "google.com"
browserHistory.visit("facebook.com");     // You are in "google.com". Visit "facebook.com"
browserHistory.visit("youtube.com");      // You are in "facebook.com". Visit "youtube.com"
browserHistory.back(1);                   // You are in "youtube.com", move back to "facebook.com" return "facebook.com"
browserHistory.back(1);                   // You are in "facebook.com", move back to "google.com" return "google.com"
browserHistory.forward(1);                // You are in "google.com", move forward to "facebook.com" return "facebook.com"
browserHistory.visit("linkedin.com");     // You are in "facebook.com". Visit "linkedin.com"
browserHistory.forward(2);                // You are in "linkedin.com", you cannot move forward any steps.
browserHistory.back(2);                   // You are in "linkedin.com", move back two steps to "facebook.com" then to "google.com". return "google.com"
browserHistory.back(7);                   // You are in "google.com", you can move back only one step to "leetcode.com". return "leetcode.com"
</pre>



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



<ul class="wp-block-list"><li><code>1 &lt;= homepage.length &lt;= 20</code></li><li><code>1 &lt;= url.length &lt;= 20</code></li><li><code>1 &lt;= steps &lt;= 100</code></li><li><code>homepage</code>&nbsp;and&nbsp;<code>url</code>&nbsp;consist of&nbsp; &#8216;.&#8217; or lower case English letters.</li><li>At most&nbsp;<code>5000</code>&nbsp;calls will be made to&nbsp;<code>visit</code>,&nbsp;<code>back</code>, and&nbsp;<code>forward</code>.</li></ul>



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



<p>Time complexity: <br>visit: Amortized O(1)<br>back: O(1)<br>forward: O(1)</p>



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class BrowserHistory {
public:
  BrowserHistory(string homepage) : 
    index_(0) {
    urls_.push_back(std::move(homepage));    
  }

  void visit(string url) {
    while (urls_.size() &gt; index_ + 1)
      urls_.pop_back();
    ++index_;
    urls_.push_back(std::move(url));
  }

  string back(int steps) {    
    index_ = max(index_ - steps, 0);
    return urls_[index_];
  }

  string forward(int steps) {
    index_ = min(index_ + steps, static_cast&lt;int&gt;(urls_.size()) - 1);  
    return urls_[index_];
  }
private:
  int index_;
  vector&lt;string&gt; urls_;
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/desgin/leetcode-1472-design-browser-history/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Python中的整型占多少个字节？</title>
		<link>https://zxi.mytechroad.com/blog/desgin/python%e4%b8%ad%e7%9a%84%e6%95%b4%e5%9e%8b%e5%8d%a0%e5%a4%9a%e5%b0%91%e4%b8%aa%e5%ad%97%e8%8a%82%ef%bc%9f/</link>
					<comments>https://zxi.mytechroad.com/blog/desgin/python%e4%b8%ad%e7%9a%84%e6%95%b4%e5%9e%8b%e5%8d%a0%e5%a4%9a%e5%b0%91%e4%b8%aa%e5%ad%97%e8%8a%82%ef%bc%9f/#comments</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 25 Nov 2019 06:11:06 +0000</pubDate>
				<category><![CDATA[Desgin]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[source code]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=5853</guid>

					<description><![CDATA[说到计算机中的整型，相信很多人都会联想到32位整型（或者int），是程序员日常生活中用的最多的一种类型。32位整型顾名思义，占用32个位也就是4个字节，取值范围−2,147,483,648~ 2,147,483,647 。C/C++中是4个字节，Java中也是4个字节，但是Python中呢？ 我们知道Python中也有int类，而且非常好用，原生支持高精度计算。但是Python中的一个整型到底占用多少字节呢？我相信绝大多数的Python程序员从未想过这一点，越是习以为常的东西越是不会在意它的存在。 在Python中，如果想要知道一个对象所占用的内存大小，只需要使用sys.getsizeof这个API就可以了。那就让我们来试一下不同的整数 [crayon-67eacd04d34b6083489978/] 从上面的小实验可以看出，一个整型最少要占24字节(0)，1开始就要占用28个字节，到了2的30次方开始要占用32个字节，而2的128次方则要占用44个字节。我们可以得到两点规律，1. 字节数随着数字增大而增大。2. 每次的增量是4个字节。 好像至此已经回答了我们的题目中的问题：Python中的整型占多少个字节？答案是：变长的（相对于int32的定长），而且最少24个字节。 你以为本文到这里就结束了吗？那你就图样图森破了。一个整型数2，居然要占用28个字节！这完全了颠覆了我的认知，我一定搞清楚为什么。 在哥们的帮助下，我找到了Python的源码。 https://github.com/python/cpython Python的官方实现是C语言，所以叫cpython。这也就意味着只要Python还在，C就会不消失。其他实现还有jython(Java), IronPython (.Net), PyPy (Python)。 第一件事情要搞清楚的是Python中int类型在cpython的名字是什么？看了半天，在 longobject.h 中发现了一个叫 PyLongObject 的结构体。然而它只是一个马甲，是 _longobject的别名。在longintrepr.h中找到了 _longobject&#8230;]]></description>
										<content:encoded><![CDATA[
<p>说到计算机中的整型，相信很多人都会联想到32位整型（或者int），是程序员日常生活中用的最多的一种类型。32位整型顾名思义，占用32个位也就是4个字节，取值范围−2,147,483,648~ 2,147,483,647 。C/C++中是4个字节，Java中也是4个字节，但是Python中呢？</p>



<p>我们知道Python中也有int类，而且非常好用，原生支持高精度计算。但是Python中的一个整型到底占用多少字节呢？我相信绝大多数的Python程序员从未想过这一点，<strong>越是习以为常的东西越是不会在意它的存在</strong>。</p>



<p>在Python中，如果想要知道一个对象所占用的内存大小，只需要使用<code>sys.getsizeof</code>这个API就可以了。那就让我们来试一下不同的整数</p>



<pre class="urvanov-syntax-highlighter-plain-tag">print(sys.getsizeof(0))        # 24
print(sys.getsizeof(1))        # 28 
print(sys.getsizeof(2))        # 28
print(sys.getsizeof(2**15))    # 28
print(sys.getsizeof(2**30))    # 32
print(sys.getsizeof(2**128))   # 44</pre>



<p>从上面的小实验可以看出，一个整型最少要占24字节(0)，1开始就要占用28个字节，到了2的30次方开始要占用32个字节，而2的128次方则要占用44个字节。我们可以得到两点规律，1. 字节数随着数字增大而增大。2. 每次的增量是4个字节。  好像至此已经回答了我们的题目中的问题：Python中的整型占多少个字节？答案是：变长的（相对于int32的定长），而且最少24个字节。  </p>



<p>你以为本文到这里就结束了吗？那你就图样图森破了。一个整型数2，居然要占用28个字节！这完全了颠覆了我的认知，我一定搞清楚为什么。 在哥们的帮助下，我找到了Python的源码。 <a href="https://github.com/python/cpython">https://github.com/python/cpython</a>  </p>



<p>Python的官方实现是C语言，所以叫cpython。这也就意味着只要Python还在，C就会不消失。其他实现还有jython(Java), IronPython (.Net), PyPy (Python)。</p>



<p>第一件事情要搞清楚的是Python中int类型在cpython的名字是什么？看了半天，在 <a href="https://github.com/python/cpython/blob/master/Include/longobject.h">longobject.h</a> 中发现了一个叫  <code>PyLongObject</code> 的结构体。然而它只是一个马甲，是 <code>_longobject</code>的别名。在<a href="https://github.com/python/cpython/blob/master/Include/longintrepr.h">longintrepr.h</a>中找到了 <code>_longobject  </code>的定义如下：</p>



<pre class="urvanov-syntax-highlighter-plain-tag">struct _longobject {
     PyObject_VAR_HEAD
     digit ob_digit[1];
 };</pre>



<p>在文件的开头就看到了<code>typedef uint32_t digit;</code>，<code>digit</code>就是<code>unit32_t</code>, 每个元素占4个字节。但<code>PyObject_VAR_HEAD</code>又是什么鬼？在<a href="https://github.com/python/cpython/blob/master/Include/object.h">object.h</a>中发现了它是个宏，上面的注释倒是挺有意思的。</p>



<pre class="urvanov-syntax-highlighter-plain-tag">/* PyObject_VAR_HEAD defines the initial segment of all variable-size
 container objects.  These end with a declaration of an array with 1
 element, but enough space is malloc'ed so that the array actually
 has room for ob_size elements.  Note that ob_size is an element count,
 not necessarily a byte count.
 */ 
 define PyObject_VAR_HEAD      PyVarObject ob_base;</pre>



<p>等一下，<code>PyVarObject</code>又是什么？还好定义就在下面。</p>



<pre class="urvanov-syntax-highlighter-plain-tag">typedef struct {
     PyObject ob_base;
     Py_ssize_t ob_size; /* Number of items in variable part */
 } PyVarObject;</pre>



<p>又一层嵌套，是不是已经晕了，继续查看<code>PyObject</code>的定义，这次反而在上面了。</p>



<pre class="urvanov-syntax-highlighter-plain-tag">typedef struct _object {
     _PyObject_HEAD_EXTRA
     Py_ssize_t ob_refcnt;
     struct _typeobject *ob_type;
 } PyObject;</pre>



<p>有完没完啊？<code>_PyObject_HEAD_EXTRA</code>又是什么？看了一下发现它只在debug build中有定义，这里就不展开了。<code>Py_ssize_t</code>等于<code>ssize_t</code>如果有定义的话， <code>ssize_t</code>在64位的机器上就是<code>long</code>。<code>_typeobject</code>又是什么？感觉应该非常大，不然就不会用指针了。不过话说回来，既然用了指针，我又何必去关心它是什么呢？反正就是8个字节而已，指向一个内存地址。至此真相大了一个白，如果我们把structs flatten,  <code>PyLongObject</code> 定义如下：</p>



<pre class="urvanov-syntax-highlighter-plain-tag">struct PyLongObject {
  long ob_refcnt;                // 8 bytes
  struct _typeobject *ob_type;   // 8 bytes
  long ob_size;                  // 8 bytes
  unsigned int ob_digit[1];      // 4 bytes * abs(ob_size)
};</pre>



<p><code>ob_refcnt</code>引用计数 8个字节，<code>ob_type</code>类型信息 8个字节（指针），<code>ob_size</code>变长部分元素的个数，8个字节。<code>ob_digit</code>变长的数据部分，字节数为4*abs(<code>ob_size</code>)，<code>ob_size</code>可以为0，所以最少8+8+8=24字节，每次增量都是4 (<code>unsigned int</code>) 的倍数。这和我们之前观察到的实验结果吻合。</p>



<p>以上都是基于64位的Python，对于32位的版本，定义如下：</p>



<pre class="urvanov-syntax-highlighter-plain-tag">struct PyLongObject {
  int ob_refcnt;                // 4 bytes
  struct _typeobject *ob_type;  // 4 bytes
  int ob_size;                  // 4 bytes
  unsigned short ob_digit[1];   // 2 bytes * abs(ob_size)
};</pre>



<p>32位就要比64位小很多了，最少12个字节，增量为2个字节。</p>



<p>好了，今天就写到这里。相信你对整型数或者Python有了一个新的认识。下面一篇我们会将会介绍整型数在Python中的表示和计算。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/desgin/python%e4%b8%ad%e7%9a%84%e6%95%b4%e5%9e%8b%e5%8d%a0%e5%a4%9a%e5%b0%91%e4%b8%aa%e5%ad%97%e8%8a%82%ef%bc%9f/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 895. Maximum Frequency Stack</title>
		<link>https://zxi.mytechroad.com/blog/desgin/leetcode-895-maximum-frequency-stack/</link>
					<comments>https://zxi.mytechroad.com/blog/desgin/leetcode-895-maximum-frequency-stack/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 26 Aug 2018 16:14:01 +0000</pubDate>
				<category><![CDATA[Desgin]]></category>
		<category><![CDATA[freq]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[priority queue]]></category>
		<category><![CDATA[stack]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=3705</guid>

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

					<description><![CDATA[Problem Given a function rand7 which generates a uniform random integer in the range 1 to 7, write a function rand10 which generates a uniform random integer in the&#8230;]]></description>
										<content:encoded><![CDATA[<h1><strong>Problem</strong></h1>
<p>Given a function <code>rand7</code> which generates a uniform random integer in the range 1 to 7, write a function <code>rand10</code> which generates a uniform random integer in the range 1 to 10.</p>
<p>Do NOT use system&#8217;s <code>Math.random()</code>.</p>
<div>
<p><strong>Example 1:</strong></p>
<pre class="crayon:false"><strong>Input: </strong><span id="example-input-1-1">1</span>
<strong>Output: </strong><span id="example-output-1">[7]</span>
</pre>
<div>
<p><strong>Example 2:</strong></p>
<pre class="crayon:false"><strong>Input: </strong><span id="example-input-2-1">2</span>
<strong>Output: </strong><span id="example-output-2">[8,4]</span>
</pre>
<div>
<p><strong>Example 3:</strong></p>
<pre class="crayon:false"><strong>Input: </strong><span id="example-input-3-1">3</span>
<strong>Output: </strong><span id="example-output-3">[8,1,10]</span>
</pre>
<p><strong>Note:</strong></p>
<ol>
<li><code>rand7</code> is predefined.</li>
<li>Each testcase has one argument: <code>n</code>, the number of times that <code>rand10</code> is called.</li>
</ol>
<h1><strong>Solution: Math</strong></h1>
<p>Time complexity: O(49/40) = O(1)</p><pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
// Running time: 112 ms
class Solution {
public:
  int rand10() {
    int target = 40;
    while (target &gt;= 40)
      target = 7 * (rand7() - 1) + (rand7() - 1);
    return target % 10 + 1;
  }
};</pre><p>Time complexity: O(7/6 + 7 / 5) = O(1)</p><pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
// Running time: 112 ms
class Solution {
public:
  int rand10() {
    int i = INT_MAX;
    int j = INT_MAX;
    while (i &gt; 6) i = rand7(); // i = [1, 2, 3, 4, 5, 6]
    while (j &gt; 5) j = rand7(); // j = [1, 2, 3, 4, 5]
    return j + 5 * (i &amp; 1);
  }
};</pre><p>&nbsp;</p>
</div>
</div>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/desgin/leetcode-872-implement-rand10-using-rand7/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[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;]]></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 class="wp-block-list"><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 class="wp-block-list"><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 class="wp-block-heading"><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="urvanov-syntax-highlighter-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="urvanov-syntax-highlighter-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="urvanov-syntax-highlighter-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>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/desgin/leetcode-622-design-circular-queue/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
