<?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>Recursion Archives - Huahua&#039;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/category/recursion/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog/category/recursion/</link>
	<description></description>
	<lastBuildDate>Thu, 12 Aug 2021 04:24:05 +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>Recursion Archives - Huahua&#039;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog/category/recursion/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>花花酱 LeetCode 1900. The Earliest and Latest Rounds Where Players Compete</title>
		<link>https://zxi.mytechroad.com/blog/recursion/leetcode-1900-the-earliest-and-latest-rounds-where-players-compete/</link>
					<comments>https://zxi.mytechroad.com/blog/recursion/leetcode-1900-the-earliest-and-latest-rounds-where-players-compete/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Thu, 12 Aug 2021 04:21:46 +0000</pubDate>
				<category><![CDATA[Recursion]]></category>
		<category><![CDATA[bitmask]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[recursion]]></category>
		<category><![CDATA[simulation]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8574</guid>

					<description><![CDATA[<p>There is a tournament where&#160;n&#160;players are participating. The players are standing in a single row and are numbered from&#160;1&#160;to&#160;n&#160;based on their&#160;initial&#160;standing position (player&#160;1&#160;is the first&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/recursion/leetcode-1900-the-earliest-and-latest-rounds-where-players-compete/">花花酱 LeetCode 1900. The Earliest and Latest Rounds Where Players Compete</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 is a tournament where&nbsp;<code>n</code>&nbsp;players are participating. The players are standing in a single row and are numbered from&nbsp;<code>1</code>&nbsp;to&nbsp;<code>n</code>&nbsp;based on their&nbsp;<strong>initial</strong>&nbsp;standing position (player&nbsp;<code>1</code>&nbsp;is the first player in the row, player&nbsp;<code>2</code>&nbsp;is the second player in the row, etc.).</p>



<p>The tournament consists of multiple rounds (starting from round number&nbsp;<code>1</code>). In each round, the&nbsp;<code>i<sup>th</sup></code>&nbsp;player from the front of the row competes against the&nbsp;<code>i<sup>th</sup></code>&nbsp;player from the end of the row, and the winner advances to the next round. When the number of players is odd for the current round, the player in the middle automatically advances to the next round.</p>



<ul><li>For example, if the row consists of players&nbsp;<code>1, 2, 4, 6, 7</code><ul><li>Player&nbsp;<code>1</code>&nbsp;competes against player&nbsp;<code>7</code>.</li><li>Player&nbsp;<code>2</code>&nbsp;competes against player&nbsp;<code>6</code>.</li><li>Player&nbsp;<code>4</code>&nbsp;automatically advances to the next round.</li></ul></li></ul>



<p>After each round is over, the winners are lined back up in the row based on the&nbsp;<strong>original ordering</strong>&nbsp;assigned to them initially (ascending order).</p>



<p>The players numbered&nbsp;<code>firstPlayer</code>&nbsp;and&nbsp;<code>secondPlayer</code>&nbsp;are the best in the tournament. They can win against any other player before they compete against each other. If any two other players compete against each other, either of them might win, and thus you may&nbsp;<strong>choose</strong>&nbsp;the outcome of this round.</p>



<p>Given the integers&nbsp;<code>n</code>,&nbsp;<code>firstPlayer</code>, and&nbsp;<code>secondPlayer</code>, return&nbsp;<em>an integer array containing two values, the&nbsp;<strong>earliest</strong>&nbsp;possible round number and the&nbsp;<strong>latest</strong>&nbsp;possible round number in which these two players will compete against each other, respectively</em>.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 11, firstPlayer = 2, secondPlayer = 4
<strong>Output:</strong> [3,4]
<strong>Explanation:</strong>
One possible scenario which leads to the earliest round number:
First round: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
Second round: 2, 3, 4, 5, 6, 11
Third round: 2, 3, 4
One possible scenario which leads to the latest round number:
First round: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
Second round: 1, 2, 3, 4, 5, 6
Third round: 1, 2, 4
Fourth round: 2, 4
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 5, firstPlayer = 1, secondPlayer = 5
<strong>Output:</strong> [1,1]
<strong>Explanation:</strong> The players numbered 1 and 5 compete in the first round.
There is no way to make them compete in any other round.
</pre>



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



<ul><li><code>2 &lt;= n &lt;= 28</code></li><li><code>1 &lt;= firstPlayer &lt; secondPlayer &lt;= n</code></li></ul>



<h2><strong>Solution 1: Simulation using recursion</strong></h2>



<p>All possible paths, <br>Time complexity: O(n<sup>2</sup>*2<sup>n</sup>)<br>Space complexity: O(logn)</p>



<p>dfs(s, i, j, d) := let i battle with j at round d, given s (binary mask of dead players).</p>



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

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  vector&lt;int&gt; earliestAndLatest(int n, int a, int b) {
    vector&lt;int&gt; ans{INT_MAX, INT_MIN};    
    function&lt;void(int, int, int, int)&gt; dfs = [&amp;](int s, int i, int j, int d) {
      while (i &lt; j &amp;&amp; s &gt;&gt; i &amp; 1) ++i;
      while (i &lt; j &amp;&amp; s &gt;&gt; j &amp; 1) --j;
      if (i &gt;= j) {
        return dfs(s, 1, n, d + 1);
      } else if (i == a &amp;&amp; j == b) {
        ans[0] = min(ans[0], d);
        ans[1] = max(ans[1], d);
      } else {
        if (i != a &amp;&amp; i != b)
          dfs(s | (1 &lt;&lt; i), i + 1, j - 1, d);
        if (j != a &amp;&amp; j != b)
          dfs(s | (1 &lt;&lt; j), i + 1, j - 1, d);
      }
    };
    dfs(0, 1, n, 1);
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/recursion/leetcode-1900-the-earliest-and-latest-rounds-where-players-compete/">花花酱 LeetCode 1900. The Earliest and Latest Rounds Where Players Compete</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/recursion/leetcode-1900-the-earliest-and-latest-rounds-where-players-compete/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1896. Minimum Cost to Change the Final Value of Expression</title>
		<link>https://zxi.mytechroad.com/blog/recursion/leetcode-1896-minimum-cost-to-change-the-final-value-of-expression/</link>
					<comments>https://zxi.mytechroad.com/blog/recursion/leetcode-1896-minimum-cost-to-change-the-final-value-of-expression/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Tue, 10 Aug 2021 06:27:59 +0000</pubDate>
				<category><![CDATA[Recursion]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[expression]]></category>
		<category><![CDATA[recursion]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8558</guid>

					<description><![CDATA[<p>You are given a&#160;valid&#160;boolean expression as a string&#160;expression&#160;consisting of the characters&#160;'1','0','&#38;'&#160;(bitwise&#160;AND&#160;operator),'&#124;'&#160;(bitwise&#160;OR&#160;operator),'(', and&#160;')'. For example,&#160;"()1&#124;1"&#160;and&#160;"(1)&#38;()"&#160;are&#160;not valid&#160;while&#160;"1",&#160;"(((1))&#124;(0))", and&#160;"1&#124;(0&#38;(1))"&#160;are&#160;valid&#160;expressions. Return&#160;the&#160;minimum cost&#160;to change the final value of the expression.&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/recursion/leetcode-1896-minimum-cost-to-change-the-final-value-of-expression/">花花酱 LeetCode 1896. Minimum Cost to Change the Final Value of Expression</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&nbsp;<strong>valid</strong>&nbsp;boolean expression as a string&nbsp;<code>expression</code>&nbsp;consisting of the characters&nbsp;<code>'1'</code>,<code>'0'</code>,<code>'&amp;'</code>&nbsp;(bitwise&nbsp;<strong>AND</strong>&nbsp;operator),<code>'|'</code>&nbsp;(bitwise&nbsp;<strong>OR</strong>&nbsp;operator),<code>'('</code>, and&nbsp;<code>')'</code>.</p>



<ul><li>For example,&nbsp;<code>"()1|1"</code>&nbsp;and&nbsp;<code>"(1)&amp;()"</code>&nbsp;are&nbsp;<strong>not valid</strong>&nbsp;while&nbsp;<code>"1"</code>,&nbsp;<code>"(((1))|(0))"</code>, and&nbsp;<code>"1|(0&amp;(1))"</code>&nbsp;are&nbsp;<strong>valid</strong>&nbsp;expressions.</li></ul>



<p>Return<em>&nbsp;the&nbsp;<strong>minimum cost</strong>&nbsp;to change the final value of the expression</em>.</p>



<ul><li>For example, if&nbsp;<code>expression = "1|1|(0&amp;0)&amp;1"</code>, its&nbsp;<strong>value</strong>&nbsp;is&nbsp;<code>1|1|(0&amp;0)&amp;1 = 1|1|0&amp;1 = 1|0&amp;1 = 1&amp;1 = 1</code>. We want to apply operations so that the<strong>&nbsp;new</strong>&nbsp;expression evaluates to&nbsp;<code>0</code>.</li></ul>



<p>The&nbsp;<strong>cost</strong>&nbsp;of changing the final value of an expression is the&nbsp;<strong>number of operations</strong>&nbsp;performed on the expression. The types of&nbsp;<strong>operations</strong>&nbsp;are described as follows:</p>



<ul><li>Turn a&nbsp;<code>'1'</code>&nbsp;into a&nbsp;<code>'0'</code>.</li><li>Turn a&nbsp;<code>'0'</code>&nbsp;into a&nbsp;<code>'1'</code>.</li><li>Turn a&nbsp;<code>'&amp;'</code>&nbsp;into a&nbsp;<code>'|'</code>.</li><li>Turn a&nbsp;<code>'|'</code>&nbsp;into a&nbsp;<code>'&amp;'</code>.</li></ul>



<p><strong>Note:</strong>&nbsp;<code>'&amp;'</code>&nbsp;does&nbsp;<strong>not</strong>&nbsp;take precedence over&nbsp;<code>'|'</code>&nbsp;in the&nbsp;<strong>order of calculation</strong>. Evaluate parentheses&nbsp;<strong>first</strong>, then in&nbsp;<strong>left-to-right</strong>&nbsp;order.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> expression = "1&amp;(0|1)"
<strong>Output:</strong> 1
<strong>Explanation:</strong> We can turn "1&amp;(0<strong>|</strong>1)" into "1&amp;(0<strong>&amp;</strong>1)" by changing the '|' to a '&amp;' using 1 operation.
The new expression evaluates to 0. 
</pre>



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



<pre class="crayon-plain-tag">&lt;strong&gt;Input:&lt;/strong&gt; expression = &quot;(0&amp;amp;0)&amp;amp;(0&amp;amp;0&amp;amp;0)&quot;
&lt;strong&gt;Output:&lt;/strong&gt; 3
&lt;strong&gt;Explanation:&lt;/strong&gt; We can turn &quot;(0&lt;strong&gt;&amp;amp;0&lt;/strong&gt;)&lt;strong&gt;&lt;u&gt;&amp;amp;&lt;/u&gt;&lt;/strong&gt;(0&amp;amp;0&amp;amp;0)&quot; into &quot;(0&lt;strong&gt;|1&lt;/strong&gt;)&lt;strong&gt;|&lt;/strong&gt;(0&amp;amp;0&amp;amp;0)&quot; using 3 operations.
The new expression evaluates to 1.</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> expression = "(0|(1|0&amp;1))"
<strong>Output:</strong> 1
<strong>Explanation:</strong> We can turn "(0|(<strong>1</strong>|0&amp;1))" into "(0|(<strong>0</strong>|0&amp;1))" using 1 operation.
The new expression evaluates to 0.</pre>



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



<ul><li><code>1 &lt;= expression.length &lt;= 10<sup>5</sup></code></li><li><code>expression</code>&nbsp;only contains&nbsp;<code>'1'</code>,<code>'0'</code>,<code>'&amp;'</code>,<code>'|'</code>,<code>'('</code>, and&nbsp;<code>')'</code></li><li>All parentheses&nbsp;are properly matched.</li><li>There will be no empty parentheses (i.e:&nbsp;<code>"()"</code>&nbsp;is not a substring of&nbsp;<code>expression</code>).</li></ul>



<h2><strong>Solution: DP, Recursion / Simulation w/ Stack</strong></h2>



<p>For each expression, stores the min cost to change value to 0 and 1.</p>



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



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

<pre class="crayon-plain-tag">class Solution {
public:
  int minOperationsToFlip(string expression) {
    stack&lt;array&lt;int, 3&gt;&gt; s;
    s.push({0, 0, 0});
    for (char e : expression) {
      if (e == '(')
        s.push({0, 0, 0});
      else if (e == '&amp;' || e == '|')
        s.top()[2] = e;
      else {        
        if (isdigit(e)) s.push({e != '0', e != '1', 0});
        auto [r0, r1, _] = s.top(); s.pop();
        auto [l0, l1, op] = s.top(); s.pop();
        if (op == '&amp;') {
          s.push({min(l0, r0),
                  min(l1 + r1, min(l1, r1) + 1),
                  0});
        } else if (op == '|') {
          s.push({min(l0 + r0, min(l0, r0) + 1),
                  min(l1, r1),
                  0});
        } else {
          s.push({r0, r1, 0});
        }
      }
    }
    return max(s.top()[0], s.top()[1]);
  }
};</pre>
</div></div>



<p></p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/recursion/leetcode-1896-minimum-cost-to-change-the-final-value-of-expression/">花花酱 LeetCode 1896. Minimum Cost to Change the Final Value of Expression</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/recursion/leetcode-1896-minimum-cost-to-change-the-final-value-of-expression/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1688. Count of Matches in Tournament</title>
		<link>https://zxi.mytechroad.com/blog/simulation/leetcode-1688-count-of-matches-in-tournament/</link>
					<comments>https://zxi.mytechroad.com/blog/simulation/leetcode-1688-count-of-matches-in-tournament/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 13 Dec 2020 20:15:36 +0000</pubDate>
				<category><![CDATA[Recursion]]></category>
		<category><![CDATA[Simulation]]></category>
		<category><![CDATA[easy]]></category>
		<category><![CDATA[O(logn)]]></category>
		<category><![CDATA[recursion]]></category>
		<category><![CDATA[simulation]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7799</guid>

					<description><![CDATA[<p>You are given an integer&#160;n, the number of teams in a tournament that has strange rules: If the current number of teams is&#160;even, each team&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/simulation/leetcode-1688-count-of-matches-in-tournament/">花花酱 LeetCode 1688. Count of Matches in Tournament</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>You are given an integer&nbsp;<code>n</code>, the number of teams in a tournament that has strange rules:</p>



<ul><li>If the current number of teams is&nbsp;<strong>even</strong>, each team gets paired with another team. A total of&nbsp;<code>n / 2</code>&nbsp;matches are played, and&nbsp;<code>n / 2</code>&nbsp;teams advance to the next round.</li><li>If the current number of teams is&nbsp;<strong>odd</strong>, one team randomly advances in the tournament, and the rest gets paired. A total of&nbsp;<code>(n - 1) / 2</code>&nbsp;matches are played, and&nbsp;<code>(n - 1) / 2 + 1</code>&nbsp;teams advance to the next round.</li></ul>



<p>Return&nbsp;<em>the number of matches played in the tournament until a winner is decided.</em></p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 7
<strong>Output:</strong> 6
<strong>Explanation:</strong> Details of the tournament: 
- 1st Round: Teams = 7, Matches = 3, and 4 teams advance.
- 2nd Round: Teams = 4, Matches = 2, and 2 teams advance.
- 3rd Round: Teams = 2, Matches = 1, and 1 team is declared the winner.
Total number of matches = 3 + 2 + 1 = 6.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 14
<strong>Output:</strong> 13
<strong>Explanation:</strong> Details of the tournament:
- 1st Round: Teams = 14, Matches = 7, and 7 teams advance.
- 2nd Round: Teams = 7, Matches = 3, and 4 teams advance.
- 3rd Round: Teams = 4, Matches = 2, and 2 teams advance.
- 4th Round: Teams = 2, Matches = 1, and 1 team is declared the winner.
Total number of matches = 7 + 3 + 2 + 1 = 13.
</pre>



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



<ul><li><code>1 &lt;= n &lt;= 200</code></li></ul>



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



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



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

<pre class="crayon-plain-tag">// Ver 1
class Solution {
public:
  int numberOfMatches(int n) {
    int ans = 0;
    while (n &amp;gt; 1) {
      ans += n / 2 + (n &amp; 1);
      n /= 2;
    }
    return ans;
  }
};
// Ver 2
class Solution {
public:
  int numberOfMatches(int n) {
    return n &amp;gt; 1 ? n / 2 + (n &amp; 1) + numberOfMatches(n / 2) : 0;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/simulation/leetcode-1688-count-of-matches-in-tournament/">花花酱 LeetCode 1688. Count of Matches in Tournament</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/simulation/leetcode-1688-count-of-matches-in-tournament/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1600. Throne Inheritance</title>
		<link>https://zxi.mytechroad.com/blog/recursion/leetcode-1600-throne-inheritance/</link>
					<comments>https://zxi.mytechroad.com/blog/recursion/leetcode-1600-throne-inheritance/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 27 Sep 2020 08:11:05 +0000</pubDate>
				<category><![CDATA[Recursion]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[hashtable]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[recursion]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7425</guid>

					<description><![CDATA[<p>A kingdom consists of a king, his children, his grandchildren, and so on. Every once in a while, someone in the family dies or a&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/recursion/leetcode-1600-throne-inheritance/">花花酱 LeetCode 1600. Throne Inheritance</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 kingdom consists of a king, his children, his grandchildren, and so on. Every once in a while, someone in the family dies or a child is born.</p>



<p>The kingdom has a well-defined order of inheritance that consists of the king as the first member. Let&#8217;s define the recursive function&nbsp;<code>Successor(x, curOrder)</code>, which given a person&nbsp;<code>x</code>&nbsp;and the inheritance order so far, returns who should be the next person after&nbsp;<code>x</code>&nbsp;in the order of inheritance.</p>



<pre class="crayon-plain-tag">Successor(x, curOrder):
    if x has no children or all of x's children are in curOrder:
        if x is the king return null
        else return Successor(x's parent, curOrder)
    else return x's oldest child who's not in curOrder</pre>



<p>For example, assume we have a kingdom that consists of the king, his children Alice and Bob (Alice is older than Bob), and finally Alice&#8217;s son Jack.</p>



<ol><li>In the beginning,&nbsp;<code>curOrder</code>&nbsp;will be&nbsp;<code>["king"]</code>.</li><li>Calling&nbsp;<code>Successor(king, curOrder)</code>&nbsp;will return Alice, so we append to&nbsp;<code>curOrder</code>&nbsp;to get&nbsp;<code>["king", "Alice"]</code>.</li><li>Calling&nbsp;<code>Successor(Alice, curOrder)</code>&nbsp;will return Jack, so we append to&nbsp;<code>curOrder</code>&nbsp;to get&nbsp;<code>["king", "Alice", "Jack"]</code>.</li><li>Calling&nbsp;<code>Successor(Jack, curOrder)</code>&nbsp;will return Bob, so we append to&nbsp;<code>curOrder</code>&nbsp;to get&nbsp;<code>["king", "Alice", "Jack", "Bob"]</code>.</li><li>Calling&nbsp;<code>Successor(Bob, curOrder)</code>&nbsp;will return&nbsp;<code>null</code>. Thus the order of inheritance will be&nbsp;<code>["king", "Alice", "Jack", "Bob"]</code>.</li></ol>



<p>Using the above function, we can always obtain a unique order of inheritance.</p>



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



<ul><li><code>ThroneInheritance(string kingName)</code>&nbsp;Initializes an object of the&nbsp;<code>ThroneInheritance</code>&nbsp;class. The name of the king is given as part of the constructor.</li><li><code>void birth(string parentName, string childName)</code>&nbsp;Indicates that&nbsp;<code>parentName</code>&nbsp;gave birth to&nbsp;<code>childName</code>.</li><li><code>void death(string name)</code>&nbsp;Indicates the death of&nbsp;<code>name</code>. The death of the person doesn&#8217;t affect the&nbsp;<code>Successor</code>&nbsp;function nor the current inheritance order. You can treat it as just marking the person as dead.</li><li><code>string[] getInheritanceOrder()</code>&nbsp;Returns a list representing the current order of inheritance&nbsp;<strong>excluding</strong>&nbsp;dead people.</li></ul>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input</strong>
["ThroneInheritance", "birth", "birth", "birth", "birth", "birth", "birth", "getInheritanceOrder", "death", "getInheritanceOrder"]
[["king"], ["king", "andy"], ["king", "bob"], ["king", "catherine"], ["andy", "matthew"], ["bob", "alex"], ["bob", "asha"], [null], ["bob"], [null]]
<strong>Output</strong>
[null, null, null, null, null, null, null, ["king", "andy", "matthew", "bob", "alex", "asha", "catherine"], null, ["king", "andy", "matthew", "alex", "asha", "catherine"]]
<strong>Explanation</strong>
ThroneInheritance t= new ThroneInheritance("king"); // order: <strong>king</strong>
t.birth("king", "andy"); // order: king &gt; <strong>andy</strong>
t.birth("king", "bob"); // order: king &gt; andy &gt; <strong>bob</strong>
t.birth("king", "catherine"); // order: king &gt; andy &gt; bob &gt; <strong>catherine</strong>
t.birth("andy", "matthew"); // order: king &gt; andy &gt; <strong>matthew</strong> &gt; bob &gt; catherine
t.birth("bob", "alex"); // order: king &gt; andy &gt; matthew &gt; bob &gt; <strong>alex</strong> &gt; catherine
t.birth("bob", "asha"); // order: king &gt; andy &gt; matthew &gt; bob &gt; alex &gt; <strong>asha</strong> &gt; catherine
t.getInheritanceOrder(); // return ["king", "andy", "matthew", "bob", "alex", "asha", "catherine"]
t.death("bob"); // order: king &gt; andy &gt; matthew &gt; <strong><s>bob</s></strong> &gt; alex &gt; asha &gt; catherine
t.getInheritanceOrder(); // return ["king", "andy", "matthew", "alex", "asha", "catherine"]
</p>
</pre>



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



<ul><li><code>1 &lt;= kingName.length, parentName.length, childName.length, name.length &lt;= 15</code></li><li><code>kingName</code>,&nbsp;<code>parentName</code>,&nbsp;<code>childName</code>, and&nbsp;<code>name</code>&nbsp;consist of lowercase English letters only.</li><li>All arguments&nbsp;<code>childName</code>&nbsp;and&nbsp;<code>kingName</code>&nbsp;are&nbsp;<strong>distinct</strong>.</li><li>All&nbsp;<code>name</code>&nbsp;arguments of&nbsp;<code>death</code>&nbsp;will be passed to either the constructor or as&nbsp;<code>childName</code>&nbsp;to&nbsp;<code>birth</code>&nbsp;first.</li><li>For each call to&nbsp;<code>birth(parentName, childName)</code>, it is guaranteed that&nbsp;<code>parentName</code>&nbsp;is alive.</li><li>At most&nbsp;<code>10<sup>5</sup></code>&nbsp;calls will be made to&nbsp;<code>birth</code>&nbsp;and&nbsp;<code>death</code>.</li><li>At most&nbsp;<code>10</code>&nbsp;calls will be made to&nbsp;<code>getInheritanceOrder</code>.</li></ul>



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



<p>Record :<br>1. mapping from parent to children (ordered)<br>2. who has dead</p>



<p>Time complexity: getInheritanceOrder O(n), other 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">// Author: Huahua
class ThroneInheritance {
public:
  ThroneInheritance(string kingName): king_(kingName) {
    m_[kingName] = {};
  }

  void birth(string parentName, string childName) {
    m_[parentName].push_back(childName);
  }

  void death(string name) {
    dead_.insert(name);
  }

  vector&lt;string&gt; getInheritanceOrder() {
    vector&lt;string&gt; ans;
    function&lt;void(const string&amp;)&gt; dfs = [&amp;](const string&amp; name) {
      if (!dead_.count(name)) ans.push_back(name);
      for (const string&amp; child: m_[name]) dfs(child);
    };
    dfs(king_);
    return ans;
  }
private:  
  string king_;  
  unordered_map&lt;string, vector&lt;string&gt;&gt; m_; // parent -&gt; list[children]
  unordered_set&lt;string&gt; dead_;
};</pre>

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

<pre class="crayon-plain-tag"># Author: Huahua
class ThroneInheritance:
  def __init__(self, kingName: str):
    self.kingName = kingName
    self.family = defaultdict(list)    
    self.dead = set()

  def birth(self, parentName: str, childName: str) -&gt; None:
    self.family[parentName].append(childName)

  def death(self, name: str) -&gt; None:
    self.dead.add(name)

  def getInheritanceOrder(self) -&gt; List[str]:
    order = []
    def dfs(name: str):
      if name not in self.dead: order.append(name)
      for child in self.family[name]: dfs(child)
    dfs(self.kingName)
    return order</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/recursion/leetcode-1600-throne-inheritance/">花花酱 LeetCode 1600. Throne Inheritance</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/recursion/leetcode-1600-throne-inheritance/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1569. Number of Ways to Reorder Array to Get Same BST</title>
		<link>https://zxi.mytechroad.com/blog/recursion/leetcode-1569-number-of-ways-to-reorder-array-to-get-same-bst/</link>
					<comments>https://zxi.mytechroad.com/blog/recursion/leetcode-1569-number-of-ways-to-reorder-array-to-get-same-bst/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 30 Aug 2020 08:48:13 +0000</pubDate>
				<category><![CDATA[Recursion]]></category>
		<category><![CDATA[combination]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[recursion]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7320</guid>

					<description><![CDATA[<p>Given an array&#160;nums&#160;that represents a permutation of integers from&#160;1&#160;to&#160;n. We are going to construct a binary search tree (BST) by inserting the elements of&#160;nums&#160;in&#160;order into&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/recursion/leetcode-1569-number-of-ways-to-reorder-array-to-get-same-bst/">花花酱 LeetCode 1569. Number of Ways to Reorder Array to Get Same BST</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Given an array&nbsp;<code>nums</code>&nbsp;that represents a permutation of integers from&nbsp;<code>1</code>&nbsp;to&nbsp;<code>n</code>. We are going to construct a binary search tree (BST) by inserting the elements of&nbsp;<code>nums</code>&nbsp;in&nbsp;order into an initially empty BST. Find the number of different ways to reorder&nbsp;<code>nums</code>&nbsp;so that the constructed BST is identical to that formed from the original array&nbsp;<code>nums</code>.</p>



<p>For example, given&nbsp;<code>nums = [2,1,3]</code>, we will have 2 as the root, 1 as a left child, and 3 as a right child. The array&nbsp;<code>[2,3,1]</code>&nbsp;also yields the same BST but&nbsp;<code>[3,2,1]</code>&nbsp;yields a different BST.</p>



<p>Return&nbsp;<em>the number of ways to reorder</em>&nbsp;<code>nums</code>&nbsp;<em>such that the BST formed is identical to the original BST formed from</em>&nbsp;<code>nums</code>.</p>



<p>Since the answer may be very large,&nbsp;<strong>return it modulo&nbsp;</strong><code>10^9 + 7</code>.</p>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2020/08/12/bb.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [2,1,3]
<strong>Output:</strong> 1
<strong>Explanation: </strong>We can reorder nums to be [2,3,1] which will yield the same BST. There are no other ways to reorder nums which will yield the same BST.
</pre>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2020/08/12/ex1.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [3,4,5,1,2]
<strong>Output:</strong> 5
<strong>Explanation: </strong>The following 5 arrays will yield the same BST: 
[3,1,2,4,5]
[3,1,4,2,5]
[3,1,4,5,2]
[3,4,1,2,5]
[3,4,1,5,2]
</pre>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2020/08/12/ex4.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [1,2,3]
<strong>Output:</strong> 0
<strong>Explanation: </strong>There are no other orderings of nums that will yield the same BST.
</pre>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2020/08/12/abc.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [3,1,2,5,4,6]
<strong>Output:</strong> 19
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [9,4,2,1,3,6,5,7,8,14,11,10,12,13,16,15,17,18]
<strong>Output:</strong> 216212978
<strong>Explanation: </strong>The number of ways to reorder nums to get the same BST is 3216212999. Taking this number modulo 10^9 + 7 gives 216212978.
</pre>



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



<ul><li><code>1 &lt;= nums.length &lt;= 1000</code></li><li><code>1 &lt;= nums[i] &lt;= nums.length</code></li><li>All integers in&nbsp;<code>nums</code>&nbsp;are&nbsp;<strong>distinct</strong>.</li></ul>



<h2><strong>Solution: Recursion + Combinatorics</strong></h2>



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



<p>For a given root (first element of the array), we can split the array into left children (nums[i] &lt; nums[0]) and right children (nums[i] &gt; nums[0]). Assuming there are l nodes for the left and r nodes for the right. We have C(l + r, l) different ways to insert l elements into a (l + r) sized array. Within node l / r nodes, we have ways(left) / ways(right) different ways to re-arrange those nodes. So the total # of ways is:<br>C(l + r, l) * ways(l) * ways(r)<br>Don&#8217;t forget to minus one for the final answer.</p>



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



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

<pre class="crayon-plain-tag">class Solution {
public:
  int numOfWays(vector&lt;int&gt;&amp; nums) {
    const int n = nums.size();
    const int kMod = 1e9 + 7;
    vector&lt;vector&lt;int&gt;&gt; cnk(n + 1, vector&lt;int&gt;(n + 1, 1));    
    for (int i = 1; i &lt;= n; ++i)      
      for (int j = 1; j &lt; i; ++j)
        cnk[i][j] = (cnk[i - 1][j] + cnk[i - 1][j - 1]) % kMod;    
    function&lt;int(vector&lt;int&gt;)&gt; trees = [&amp;](const vector&lt;int&gt;&amp; nums) {
      const int n = nums.size();
      if (n &lt;= 2) return 1;
      vector&lt;int&gt; left;
      vector&lt;int&gt; right;
      for (int i = 1; i &lt; nums.size(); ++i)
        if (nums[i] &lt; nums[0]) left.push_back(nums[i]);
        else right.push_back(nums[i]);
      long ans = cnk[n - 1][left.size()];
      ans = (ans * trees(left)) % kMod;      
      ans = (ans * trees(right)) % kMod;      
      return static_cast&lt;int&gt;(ans);
    };
    return trees(nums) - 1;
  } 
};</pre>

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

<pre class="crayon-plain-tag">class Solution:
  def numOfWays(self, nums: List[int]) -&gt; int:
    def ways(nums):
      if len(nums) &lt;= 2: return 1
      l = [x for x in nums if x &lt; nums[0]]
      r = [x for x in nums if x &gt; nums[0]]
      return comb(len(l) + len(r), len(l)) * ways(l) * ways(r)
    return (ways(nums) - 1) % (10**9 + 7)</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/recursion/leetcode-1569-number-of-ways-to-reorder-array-to-get-same-bst/">花花酱 LeetCode 1569. Number of Ways to Reorder Array to Get Same BST</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/recursion/leetcode-1569-number-of-ways-to-reorder-array-to-get-same-bst/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 224. Basic Calculator</title>
		<link>https://zxi.mytechroad.com/blog/recursion/leetcode-224-basic-calculator/</link>
					<comments>https://zxi.mytechroad.com/blog/recursion/leetcode-224-basic-calculator/#comments</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 09 Mar 2020 20:33:55 +0000</pubDate>
				<category><![CDATA[Recursion]]></category>
		<category><![CDATA[calculator]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[recursion]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=6438</guid>

					<description><![CDATA[<p>Implement a basic calculator to evaluate a simple expression string. The expression string may contain open&#160;(&#160;and closing parentheses&#160;), the plus&#160;+&#160;or minus sign&#160;-,&#160;non-negative&#160;integers and empty spaces&#160;.&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/recursion/leetcode-224-basic-calculator/">花花酱 LeetCode 224. Basic Calculator</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>Implement a basic calculator to evaluate a simple expression string.</p>



<p>The expression string may contain open&nbsp;<code>(</code>&nbsp;and closing parentheses&nbsp;<code>)</code>, the plus&nbsp;<code>+</code>&nbsp;or minus sign&nbsp;<code>-</code>,&nbsp;<strong>non-negative</strong>&nbsp;integers and empty spaces&nbsp;.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> "1 + 1"
<strong>Output:</strong> 2
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> " 2-1 + 2 "
<strong>Output:</strong> 3</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> "(1+(4+5+2)-3)+(6+8)"
<strong>Output:</strong> 23</pre>



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



<ul><li>You may assume that the given expression is always valid.</li><li><strong>Do not</strong>&nbsp;use the&nbsp;<code>eval</code>&nbsp;built-in library function.</li></ul>



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



<p>Make a recursive call when there is an open parenthesis and return if there is close parenthesis.</p>



<p>Time complexity: O(n)<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 Solution {
public:
  int calculate(string s) {    
    function&lt;int(int&amp;)&gt; eval = [&amp;](int&amp; pos) {
      int ret = 0;
      int sign = 1;
      int val = 0;
      while (pos &lt; s.size()) {
        const char ch = s[pos];
        if (isdigit(ch)) {
          val = val * 10 + (s[pos++] - '0');
        } else if (ch == '+' || ch == '-') {
          ret += sign * val;
          val = 0;
          sign = ch == '+' ? 1 : -1;
          ++pos;
        } else if (ch == '(') {
          val = eval(++pos);
        } else if (ch == ')') {          
          ++pos;
          break;
        } else {
          ++pos;
        }
      }
      return ret += sign * val;
    };
    int pos = 0;
    return eval(pos);
  }
};</pre>
</div></div>



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

<pre class="crayon-plain-tag"># Author: Huahua
class Solution:
  def calculate(self, s: str) -&gt; int:
    self.pos = 0    
    def eval():
      val = 0
      sign = 1
      ret = 0
      while self.pos &lt; len(s):
        ch = s[self.pos]
        if ch == ' ':
          self.pos += 1
        elif ch == '(':
          self.pos += 1
          val = eval()
        elif ch == ')':
          self.pos += 1
          ret += sign * val
          return ret
        elif ch == '+' or ch == '-':
          ret += sign * val
          val = 0
          sign = 1 if ch == '+' else -1
          self.pos += 1
        else:
          val = val * 10 + (ord(ch) - ord('0'))
          self.pos += 1
      ret += val * sign
      return ret
    return eval()</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/recursion/leetcode-224-basic-calculator/">花花酱 LeetCode 224. Basic Calculator</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/recursion/leetcode-224-basic-calculator/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1140. Stone Game II</title>
		<link>https://zxi.mytechroad.com/blog/recursion/leetcode-1140-stone-game-ii/</link>
					<comments>https://zxi.mytechroad.com/blog/recursion/leetcode-1140-stone-game-ii/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 28 Jul 2019 05:47:25 +0000</pubDate>
				<category><![CDATA[Recursion]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[game]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[recursion]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=5368</guid>

					<description><![CDATA[<p>Alex&#160;and Lee continue their&#160;games with piles of stones.&#160; There are a number of&#160;piles&#160;arranged in a row, and each pile has a positive integer number of&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/recursion/leetcode-1140-stone-game-ii/">花花酱 LeetCode 1140. Stone Game II</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<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/e_FrC5xavwI?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div></figure>



<p>Alex&nbsp;and Lee continue their&nbsp;games with piles of stones.&nbsp; There are a number of&nbsp;piles&nbsp;<strong>arranged in a row</strong>, and each pile has a positive integer number of stones&nbsp;<code>piles[i]</code>.&nbsp; The objective of the game is to end with the most&nbsp;stones.&nbsp;</p>



<p>Alex and Lee take turns, with Alex starting first.&nbsp; Initially,&nbsp;<code>M = 1</code>.</p>



<p>On each player&#8217;s turn, that player&nbsp;can take&nbsp;<strong>all the stones</strong>&nbsp;in the&nbsp;<strong>first</strong>&nbsp;<code>X</code>&nbsp;remaining piles, where&nbsp;<code>1 &lt;= X &lt;= 2M</code>.&nbsp; Then, we set&nbsp;<code>M = max(M, X)</code>.</p>



<p>The game continues until all the stones have been taken.</p>



<p>Assuming Alex and Lee play optimally, return the maximum number of stones Alex can get.</p>



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



<pre class="wp-block-preformatted; crayon:false"><strong>Input:</strong> piles = [2,7,9,4,4]
<strong>Output:</strong> 10
<strong>Explanation:</strong>  If Alex takes one pile at the beginning, Lee takes two piles, then Alex takes 2 piles again. Alex can get 2 + 4 + 4 = 10 piles in total. If Alex takes two piles at the beginning, then Lee can take all three piles left. In this case, Alex get 2 + 7 = 9 piles in total. So we return 10 since it's larger. 
</pre>



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



<ul><li><code>1 &lt;= piles.length &lt;= 100</code></li><li><code>1 &lt;= piles[i]&nbsp;&lt;= 10 ^ 4</code></li></ul>



<h2><strong>Solution: Recursion + Memoization</strong></h2>



<p>def solve(s, m) = max diff score between two players starting from s for the given M.</p>



<p>cache[s][M] = max{sum(piles[s:s+x]) &#8211; solve(s+x, max(x, M)}, 1 &lt;= x &lt;= 2*M, s + x &lt;= n</p>



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



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

<pre class="crayon-plain-tag">// Author: Huahua, 12 ms / 9.7 MB
class Solution {
public:
  int stoneGameII(vector&lt;int&gt;&amp; piles) {
    const int n = piles.size();
    unordered_map&lt;int, int&gt; cache;
    // Maximum diff starting from piles[s] given M.
    function&lt;int(int, int)&gt; solve = [&amp;](int s, int M) {
      if (s &gt;= n) return 0;
      const int key = (s &lt;&lt; 8) | M;
      if (cache.count(key)) return cache[key];
      int best = INT_MIN;
      int curr = 0;
      for (int x = 1; x &lt;= 2 * M; ++x) {
        if (s + x &gt; n) break;
        curr += piles[s + x - 1];
        best = max(best, curr - solve(s + x, max(x, M)));
      }
      return cache[key] = best;
    };    
    int total = accumulate(begin(piles), end(piles), 0);
    return  (total + solve(0, 1)) / 2;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/recursion/leetcode-1140-stone-game-ii/">花花酱 LeetCode 1140. Stone Game II</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/recursion/leetcode-1140-stone-game-ii/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1106. Parsing A Boolean Expression</title>
		<link>https://zxi.mytechroad.com/blog/recursion/leetcode-1106-parsing-a-boolean-expression/</link>
					<comments>https://zxi.mytechroad.com/blog/recursion/leetcode-1106-parsing-a-boolean-expression/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 01 Jul 2019 06:32:46 +0000</pubDate>
				<category><![CDATA[Recursion]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[parser]]></category>
		<category><![CDATA[recursion]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=5272</guid>

					<description><![CDATA[<p>Return the result of evaluating a given boolean&#160;expression, represented as a string. An expression can either be: "t", evaluating to&#160;True; "f", evaluating to&#160;False; "!(expr)", evaluating&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/recursion/leetcode-1106-parsing-a-boolean-expression/">花花酱 LeetCode 1106. Parsing A Boolean Expression</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/y2kFBqj_J08?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div></figure>



<p>Return the result of evaluating a given boolean&nbsp;<code>expression</code>, represented as a string.</p>



<p>An expression can either be:</p>



<ul><li><code>"t"</code>, evaluating to&nbsp;<code>True</code>;</li><li><code>"f"</code>, evaluating to&nbsp;<code>False</code>;</li><li><code>"!(expr)"</code>, evaluating to the logical NOT of the inner expression&nbsp;<code>expr</code>;</li><li><code>"&amp;(expr1,expr2,...)"</code>, evaluating to the logical AND of 2 or more inner expressions&nbsp;<code>expr1, expr2, ...</code>;</li><li><code>"|(expr1,expr2,...)"</code>, evaluating to the logical OR of 2 or more inner expressions&nbsp;<code>expr1, expr2, ...</code></li></ul>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> expression = "!(f)"
<strong>Output:</strong> true
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> expression = "|(f,t)"
<strong>Output:</strong> true
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> expression = "&amp;(t,f)"
<strong>Output:</strong> false
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> expression = "|(&amp;(t,f,t),!(t))"
<strong>Output:</strong> false</pre>



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



<p>Time complexity: O(n)<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 Solution {
public:
  bool parseBoolExpr(string expression) {
    int s = 0;
    return parse(expression, s);
  }
private:  
  bool parse(const string&amp;amp; exp, int&amp;amp; s) {
    char ch = exp[s++];    
    if (ch == 't') return true;      
    if (ch == 'f') return false;
    if (ch == '!') {
      bool ans = !parse(exp, ++s);
      ++s;
      return ans;
    } 
    bool is_and = (ch == '&amp;amp;');
    bool ans = is_and;
    ++s;
    while (true) {
      if (is_and) ans &amp;amp;= parse(exp, s);
      else ans |= parse(exp, s);
      if (exp[s++] == ')') break;
    }
    return ans;
  }
};</pre>

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

<pre class="crayon-plain-tag">class Solution {
  private int s;
  private char[] exp;
  public boolean parseBoolExpr(String expression) {
    exp = expression.toCharArray();
    s = 0;
    return parse() == 1;
  }
      
  private int parse() {
    char ch = exp[s++];
    if (ch == 't') return 1;
    if (ch == 'f') return 0;
    if (ch == '!') {
      ++s;
      int ans = 1 - parse();
      ++s;
      return ans;
    }
    boolean is_and = (ch == '&amp;');
    int ans = is_and ? 1 : 0;
    ++s;
    while (true) {
      if (is_and) ans &amp;= parse();
      else ans |= parse();
      if (exp[s++] == ')') break;
    }
    return ans;
  }
}</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/recursion/leetcode-1106-parsing-a-boolean-expression/">花花酱 LeetCode 1106. Parsing A Boolean Expression</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/recursion/leetcode-1106-parsing-a-boolean-expression/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 394. Decode String</title>
		<link>https://zxi.mytechroad.com/blog/recursion/leetcode-394-decode-string/</link>
					<comments>https://zxi.mytechroad.com/blog/recursion/leetcode-394-decode-string/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Thu, 11 Apr 2019 06:13:56 +0000</pubDate>
				<category><![CDATA[Recursion]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[recursion]]></category>
		<category><![CDATA[stack]]></category>
		<category><![CDATA[string]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=5041</guid>

					<description><![CDATA[<p>Given an encoded string, return it&#8217;s decoded string. The encoding rule is:&#160;k[encoded_string], where the&#160;encoded_string&#160;inside the square brackets is being repeated exactly&#160;k&#160;times. Note that&#160;k&#160;is guaranteed to&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/recursion/leetcode-394-decode-string/">花花酱 LeetCode 394. Decode String</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>Given an encoded string, return it&#8217;s decoded string.</p>



<p>The encoding rule is:&nbsp;<code>k[encoded_string]</code>, where the&nbsp;<em>encoded_string</em>&nbsp;inside the square brackets is being repeated exactly&nbsp;<em>k</em>&nbsp;times. Note that&nbsp;<em>k</em>&nbsp;is guaranteed to be a positive integer.</p>



<p>You may assume that the input string is always valid; No extra white spaces, square brackets are well-formed, etc.</p>



<p>Furthermore, you may assume that the original data does not contain any digits and that digits are only for those repeat numbers,&nbsp;<em>k</em>. For example, there won&#8217;t be input like&nbsp;<code>3a</code>&nbsp;or&nbsp;<code>2[4]</code>.</p>



<p><strong>Examples:</strong></p>



<pre class="wp-block-preformatted; crayon:false">s = "3[a]2[bc]", return "aaabcbc".
s = "3[a2[c]]", return "accaccacc".
s = "2[abc]3[cd]ef", return "abcabccdcdcdef".</pre>



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



<p>Time complexity: O(n^2)<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, 4ms
class Solution {
public:
  string decodeString(string s) {
    if (s.empty()) return &quot;&quot;;    
    string ans;
    int i = 0;
    int n = s.length();
    int c = 0;
    while (isdigit(s[i]) &amp;&amp; i &lt; n) 
      c = c * 10 + (s[i++] - '0');
    
    int j = i;
    if (i &lt; n &amp;&amp; s[i] == '[') {      
      int open = 1;
      while (++j &lt; n &amp;&amp; open) {
        if (s[j] == '[') ++open;
        if (s[j] == ']') --open;
      }
    } else {
      while (j &lt; n &amp;&amp; isalpha(s[j])) ++j;
    }    
    
    // &quot;def2[ac]&quot; =&gt; &quot;def&quot; + decodeString(&quot;2[ac]&quot;)
    //  |  |
    //  i  j
    if (i == 0)
      return s.substr(0, j) + decodeString(s.substr(j));
    
    // &quot;3[a2[c]]ef&quot;, ss = decodeString(&quot;a2[c]&quot;) = &quot;acc&quot;
    //   |      |
    //   i      j
    string ss = decodeString(s.substr(i + 1, j - i - 2));    
    while (c--)
      ans += ss;
    // &quot;3[a2[c]]ef&quot;, ans = &quot;abcabcabc&quot;, ans += decodeString(&quot;ef&quot;)
    ans += decodeString(s.substr(j));
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/recursion/leetcode-394-decode-string/">花花酱 LeetCode 394. Decode String</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/recursion/leetcode-394-decode-string/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 464. Can I Win</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-464-can-i-win/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-464-can-i-win/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 04 Feb 2018 17:17:44 +0000</pubDate>
				<category><![CDATA[Recursion]]></category>
		<category><![CDATA[Search]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[min-max]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=1751</guid>

					<description><![CDATA[<p>题目大意：两个人从1到M中每次取出一个数加到当前的总和上，第一个达到或超过T的人获胜。问你第一个玩家能不能获胜。 In the &#8220;100 game,&#8221; two players take turns adding, to a running total, any integer from 1..10. The player who first causes the running&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-464-can-i-win/">花花酱 LeetCode 464. Can I Win</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/GNZIAbf0gT0?feature=oembed" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe></p>
<p>题目大意：两个人从1到M中每次取出一个数加到当前的总和上，第一个达到或超过T的人获胜。问你第一个玩家能不能获胜。</p>
<p>In the &#8220;100 game,&#8221; two players take turns adding, to a running total, any integer from 1..10. The player who first causes the running total to reach or exceed 100 wins.</p>
<p>What if we change the game so that players cannot re-use integers?</p>
<p>For example, two players might take turns drawing from a common pool of numbers of 1..15 without replacement until they reach a total &gt;= 100.</p>
<p>Given an integer <code>maxChoosableInteger</code> and another integer <code>desiredTotal</code>, determine if the first player to move can force a win, assuming both players play optimally.</p>
<p>You can always assume that <code>maxChoosableInteger</code> will not be larger than 20 and <code>desiredTotal</code> will not be larger than 300.</p>
<p><b>Example</b></p><pre class="crayon-plain-tag">Input:
maxChoosableInteger = 10
desiredTotal = 11

Output:
false

Explanation:
No matter which integer the first player choose, the first player will lose.
The first player can choose an integer from 1 up to 10.
If the first player choose 1, the second player can only choose integers from 2 up to 10.
The second player will win by choosing 10 and get a total = 11, which is &amp;gt;= desiredTotal.
Same with other integers chosen by the first player, the second player will always win.</pre><p>&nbsp;</p>
<p>&nbsp;</p>
<p><img class="alignnone size-full wp-image-1759" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2018/02/464-ep165.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/02/464-ep165.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/02/464-ep165-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/02/464-ep165-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p><img class="alignnone size-full wp-image-1758" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2018/02/464-ep165-2.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2018/02/464-ep165-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/02/464-ep165-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2018/02/464-ep165-2-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></p>
<p><b>Solution: Recursion with memoization </b></p>
<p>Time complexity: O(2^M)</p>
<p>Space complexity: O(2^M)</p>
<p>C++</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 19 ms (&lt;98.70%)
class Solution {
public:
  bool canIWin(int M, int T) {
    const int sum = M * (M + 1) / 2;
    if (sum &lt; T) return false;
    if (T &lt;= 0) return true;
    m_ = vector&lt;char&gt;(1 &lt;&lt; M, 0);
    return canIWin(M, T, 0);
  }
private:
  vector&lt;char&gt; m_; // 0: unknown, 1: won, -1: lost
  bool canIWin(int M, int T, int state) {
    if (T &lt;= 0) return false;
    if (m_[state]) return m_[state] == 1;
    for (int i = 0; i &lt; M; ++i) {
      if (state &amp; (1 &lt;&lt; i)) continue; // number i used      
      // The next player can not win, current player wins
      if (!canIWin(M, T - (i + 1), state | (1 &lt;&lt; i))) 
        return m_[state] = 1;
    }
    // Current player loses.
    m_[state] = -1;
    return false;
  }
};</pre><p>Java</p><pre class="crayon-plain-tag">// Author: Huahua
// Running time: 20 ms
class Solution {
  private byte[] m_;
  public boolean canIWin(int M, int T) {
    int sum = M * (M + 1) / 2;
    if (sum &lt; T) return false;
    if (T &lt;= 0) return true;
    m_ = new byte[1 &lt;&lt; M];
    return canIWin(M, T, 0);
  }
  
  private boolean canIWin(int M, int T, int state) {
    if (T &lt;= 0) return false;
    if (m_[state] != 0) return m_[state] == 1;
    
    for (int i = 0; i &lt; M; ++i) {
      if ((state &amp; (1 &lt;&lt; i)) &gt; 0) continue;
      if (!canIWin(M, T - (i + 1), state | (1 &lt;&lt; i))) {
        m_[state] = 1;
        return true;
      }
    }
    m_[state] = -1;
    return false;
  }    
}</pre><p>Python3</p><pre class="crayon-plain-tag">"""
Author: Huahua
Running time: 706 ms
"""
class Solution:
  def canIWin(self, M, T):
    def win(M, T, m, state):
      if T &lt;= 0: return False
      if m[state] != 0: return m[state] == 1
      for i in range(M):
        if (state &amp; (1 &lt;&lt; i)) &gt; 0: continue
        if not win(M, T - i - 1, m, state | (1 &lt;&lt; i)):
          m[state] = 1
          return True
      m[state] = -1
      return False
    
    s = M * (M + 1) / 2
    if s &lt; T: return False
    if T &lt;= 0: return True
    if s == T: return (M % 2) == 1
    
    m = [0] * (1 &lt;&lt; M)
    return win(M, T, m, 0)</pre><p>&nbsp;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-464-can-i-win/">花花酱 LeetCode 464. Can I Win</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/searching/leetcode-464-can-i-win/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 736. Parse Lisp Expression</title>
		<link>https://zxi.mytechroad.com/blog/recursion/leetcode-736-parse-lisp-expression/</link>
					<comments>https://zxi.mytechroad.com/blog/recursion/leetcode-736-parse-lisp-expression/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Fri, 01 Dec 2017 09:18:37 +0000</pubDate>
				<category><![CDATA[Recursion]]></category>
		<category><![CDATA[eval]]></category>
		<category><![CDATA[expression]]></category>
		<category><![CDATA[lisp]]></category>
		<category><![CDATA[parser]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=1052</guid>

					<description><![CDATA[<p>Problem: You are given a string expression representing a Lisp-like expression to return the integer value of. The syntax for these expressions is given as follows. An&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/recursion/leetcode-736-parse-lisp-expression/">花花酱 LeetCode 736. Parse Lisp Expression</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/C75nVjzsT9g?feature=oembed" frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen></iframe></p>
<p><strong>Problem:</strong></p>
<p>You are given a string <code>expression</code> representing a Lisp-like expression to return the integer value of.</p>
<p>The syntax for these expressions is given as follows.</p>
<ul>
<li>An expression is either an integer, a let-expression, an add-expression, a mult-expression, or an assigned variable. Expressions always evaluate to a single integer.</li>
<li>(An integer could be positive or negative.)</li>
<li>A let-expression takes the form <code>(let v1 e1 v2 e2 ... vn en expr)</code>, where <code>let</code> is always the string <code>"let"</code>, then there are 1 or more pairs of alternating variables and expressions, meaning that the first variable <code>v1</code>is assigned the value of the expression <code>e1</code>, the second variable <code>v2</code> is assigned the value of the expression <code>e2</code>, and so on <b>sequentially</b>; and then the value of this let-expression is the value of the expression <code>expr</code>.</li>
<li>An add-expression takes the form <code>(add e1 e2)</code> where <code>add</code> is always the string <code>"add"</code>, there are always two expressions <code>e1, e2</code>, and this expression evaluates to the addition of the evaluation of <code>e1</code> and the evaluation of <code>e2</code>.</li>
<li>A mult-expression takes the form <code>(mult e1 e2)</code> where <code>mult</code> is always the string <code>"mult"</code>, there are always two expressions <code>e1, e2</code>, and this expression evaluates to the multiplication of the evaluation of <code>e1</code> and the evaluation of <code>e2</code>.</li>
<li>For the purposes of this question, we will use a smaller subset of variable names. A variable starts with a lowercase letter, then zero or more lowercase letters or digits. Additionally for your convenience, the names &#8220;add&#8221;, &#8220;let&#8221;, or &#8220;mult&#8221; are protected and will never be used as variable names.</li>
<li>Finally, there is the concept of scope. When an expression of a variable name is evaluated, <b>within the context of that evaluation</b>, the innermost scope (in terms of parentheses) is checked first for the value of that variable, and then outer scopes are checked sequentially. It is guaranteed that every expression is legal. Please see the examples for more details on scope.</li>
</ul>
<p><b>Evaluation Examples:</b></p><pre class="crayon-plain-tag">Input: (add 1 2)
Output: 3

Input: (mult 3 (add 2 3))
Output: 15

Input: (let x 2 (mult x 5))
Output: 10

Input: (let x 2 (mult x (let x 3 y 4 (add x y))))
Output: 14
Explanation: In the expression (add x y), when checking for the value of the variable x,
we check from the innermost scope to the outermost in the context of the variable we are trying to evaluate.
Since x = 3 is found first, the value of x is 3.

Input: (let x 3 x 2 x)
Output: 2
Explanation: Assignment in let statements is processed sequentially.

Input: (let x 1 y 2 x (add x y) (add x y))
Output: 5
Explanation: The first (add x y) evaluates as 3, and is assigned to x.
The second (add x y) evaluates as 3+2 = 5.

Input: (let x 2 (add (let x 3 (let x 4 x)) x))
Output: 6
Explanation: Even though (let x 4 x) has a deeper scope, it is outside the context
of the final x in the add-expression.  That final x will equal 2.

Input: (let a1 3 b2 (add a1 1) b2) 
Output 4
Explanation: Variable names can contain digits after the first character.</pre><p><b>Note:</b></p>
<ul>
<li>The given string <code>expression</code> is well formatted: There are no leading or trailing spaces, there is only a single space separating different components of the string, and no space between adjacent parentheses. The expression is guaranteed to be legal and evaluate to an integer.</li>
<li>The length of <code>expression</code> is at most 2000. (It is also non-empty, as that would not be a legal expression.)</li>
<li>The answer and all intermediate calculations of that answer are guaranteed to fit in a 32-bit integer.</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><br />
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></p>
<p><strong>Idea:</strong></p>
<p>Recursive parsing</p>
<p>Time complexity: O(n^2) in worst case O(n) in practice</p>
<p>Space complexity: O(n)</p>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/736-ep119-1.png"><img class="alignnone size-full wp-image-1063" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/736-ep119-1.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/736-ep119-1.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/736-ep119-1-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/736-ep119-1-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<p>&nbsp;</p>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/736-ep119-2.png"><img class="alignnone size-full wp-image-1062" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/736-ep119-2.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/736-ep119-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/736-ep119-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/736-ep119-2-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
<p>&nbsp;</p>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/736-ep119-3.png"><img class="alignnone size-full wp-image-1061" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/736-ep119-3.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/736-ep119-3.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/736-ep119-3-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/12/736-ep119-3-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 3 ms
class Solution {
public:
    int evaluate(string expression) {        
        scopes_.clear();
        int pos = 0;
        return eval(expression, pos);
    }
private:
    int eval(const string&amp; s, int&amp; pos) {
        scopes_.push_front(unordered_map&lt;string, int&gt;());
        int value = 0; // The return value of current expr        
        if (s[pos] == '(') ++pos;

        // command, variable or number
        const string token = getToken(s, pos);

        if (token == "add") {
            int v1 = eval(s, ++pos);
            int v2 = eval(s, ++pos);
            value = v1 + v2;
        } else if (token == "mult") {
            int v1 = eval(s, ++pos);
            int v2 = eval(s, ++pos);
            value = v1 * v2;
        } else if (token == "let") {
            string var;
            // expecting " var1 exp1 var2 exp2 ... last_expr)"
            while (s[pos] != ')') {
                ++pos;
                // Must be last_expr
                if (s[pos] == '(') {
                    value = eval(s, ++pos);
                    break;
                }                
                // Get a token, could be "x" or "-12" for last_expr
                var = getToken(s, pos);                
                // End of let, var is last_expr
                if (s[pos] == ')') {
                    if (isalpha(var[0]))
                        value = getValue(var);
                    else
                        value = stoi(var);
                    break;
                }
                // x -12 -&gt; set x to -12 and store in the current scope and take it as the current return value
                value = scopes_.front()[var] = eval(s, ++pos);
            }
        } else if (isalpha(token[0])) {            
            value = getValue(token); // symbol
        } else {            
            value = std::stoi(token); // number
        }
        if (s[pos] == ')') ++pos;        
        scopes_.pop_front();        
        return value;
    }
    
    int getValue(const string&amp; symbol) {
        for (const auto&amp; scope : scopes_)        
            if (scope.count(symbol)) return scope.at(symbol);
        return 0;
    }
    
    // Get a token from current pos.
    // "let x" -&gt; "let"
    // "-12 (add x y)" -&gt; "-12"
    string getToken(const string&amp; s, int&amp; pos) {        
        string token;
        while (pos &lt; s.length()) {            
            if (s[pos] == ')' || s[pos] == ' ') break;
            token += s[pos++];
        }
        return token;
    }
    
    deque&lt;unordered_map&lt;string, int&gt;&gt; scopes_; 
};</pre><p>&nbsp;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/recursion/leetcode-736-parse-lisp-expression/">花花酱 LeetCode 736. Parse Lisp Expression</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/recursion/leetcode-736-parse-lisp-expression/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 726. Number of Atoms</title>
		<link>https://zxi.mytechroad.com/blog/string/leetcode-726-number-of-atoms/</link>
					<comments>https://zxi.mytechroad.com/blog/string/leetcode-726-number-of-atoms/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Thu, 16 Nov 2017 06:09:20 +0000</pubDate>
				<category><![CDATA[Hard]]></category>
		<category><![CDATA[Recursion]]></category>
		<category><![CDATA[String]]></category>
		<category><![CDATA[DFS]]></category>
		<guid isPermaLink="false">http://zxi.mytechroad.com/blog/?p=810</guid>

					<description><![CDATA[<p>&#160; Problem: Given a chemical formula (given as a string), return the count of each atom. An atomic element always starts with an uppercase character, then zero&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/string/leetcode-726-number-of-atoms/">花花酱 LeetCode 726. Number of Atoms</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>&nbsp;</p>
<div class="question-description">
<p><iframe width="500" height="375" src="https://www.youtube.com/embed/6nQ2jfs7a7I?feature=oembed" frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen></iframe></p>
<p><strong>Problem:</strong></p>
<p>Given a chemical <code>formula</code> (given as a string), return the count of each atom.</p>
<p>An atomic element always starts with an uppercase character, then zero or more lowercase letters, representing the name.</p>
<p>1 or more digits representing the count of that element may follow if the count is greater than 1. If the count is 1, no digits will follow. For example, H2O and H2O2 are possible, but H1O2 is impossible.</p>
<p>Two formulas concatenated together produce another formula. For example, H2O2He3Mg4 is also a formula.</p>
<p>A formula placed in parentheses, and a count (optionally added) is also a formula. For example, (H2O2) and (H2O2)3 are formulas.</p>
<p>Given a formula, output the count of all elements as a string in the following form: the first name (in sorted order), followed by its count (if that count is more than 1), followed by the second name (in sorted order), followed by its count (if that count is more than 1), and so on.</p>
<p><b>Example 1:</b></p><pre class="crayon-plain-tag">Input: 
formula = "H2O"
Output: "H2O"
Explanation: 
The count of elements are {'H': 2, 'O': 1}.</pre><p><b>Example 2:</b></p><pre class="crayon-plain-tag">Input: 
formula = &quot;Mg(OH)2&quot;
Output: &quot;H2MgO2&quot;
Explanation: 
The count of elements are {'H': 2, 'Mg': 1, 'O': 2}.</pre><p><b>Example 3:</b></p><pre class="crayon-plain-tag">Input: 
formula = &quot;K4(ON(SO3)2)2&quot;
Output: &quot;K4N2O14S4&quot;
Explanation: 
The count of elements are {'K': 4, 'N': 2, 'O': 14, 'S': 4}.</pre><p><b>Note:</b></p>
<ul>
<li>All atom names consist of lowercase letters, except for the first character which is uppercase.</li>
<li>The length of <code>formula</code> will be in the range <code>[1, 1000]</code>.</li>
<li><code>formula</code> will only consist of letters, digits, and round parentheses, and is a valid formula as defined in the problem.</li>
</ul>
<p>&nbsp;</p>
<p><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script><br />
<ins class="adsbygoogle" style="display: block; text-align: center;" data-ad-layout="in-article" data-ad-format="fluid" data-ad-client="ca-pub-2404451723245401" data-ad-slot="7983117522"></ins><br />
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></p>
<p><strong>Idea:</strong></p>
<p>Recursion</p>
<p>Time complexity: O(n)</p>
<p>Space complexity: O(n)</p>
<p><a href="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/726-ep108.png"><img class="alignnone size-full wp-image-815" src="http://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/726-ep108.png" alt="" width="960" height="540" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/726-ep108.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/726-ep108-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/726-ep108-768x432.png 768w, https://zxi.mytechroad.com/blog/wp-content/uploads/2017/11/726-ep108-624x351.png 624w" sizes="(max-width: 960px) 100vw, 960px" /></a></p>
</div>
<p><strong>Solution:</strong></p>
<p>C++</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 3 ms
class Solution {
public:
    string countOfAtoms(const string&amp; formula) {
        int i = 0;
        string ans;
        for (const auto&amp; kv : countOfAtoms(formula, i)) {
            ans += kv.first;
            if (kv.second &gt; 1) ans += std::to_string(kv.second);
        }
        return ans;
    }
private:    
    map&lt;string, int&gt; countOfAtoms(const string&amp; formula, int&amp; i) {
        map&lt;string, int&gt; counts;
        while (i != formula.length()) {
            if (formula[i] == '(') {                
                const auto&amp; tmp_counts = countOfAtoms(formula, ++i);
                const int count = getCount(formula, i);
                for (const auto&amp; kv : tmp_counts)
                    counts[kv.first] += kv.second * count;
            } else if (formula[i] == ')') {
                ++i;
                return counts;
            } else {
                const string&amp; name = getName(formula, i);
                counts[name] += getCount(formula, i);
            }
        }
        return counts;
    }
    
    string getName(const string&amp; formula, int&amp; i) {
        string name;
        while (isalpha(formula[i]) 
           &amp;&amp; (name.empty() || islower(formula[i]))) name += formula[i++];
        return name;
    }
    
    int getCount(const string&amp; formula, int&amp; i) {
        string count_str;
        while (isdigit(formula[i])) count_str += formula[i++];
        return count_str.empty() ? 1 : std::stoi(count_str);
    }    
};</pre><p>&nbsp;</p>
<p>Java</p><pre class="crayon-plain-tag">// Author: Huahua
// Runtime: 13 ms
class Solution {
    private int i;    
    public String countOfAtoms(String formula) {
        StringBuilder ans = new StringBuilder();
        i = 0;
        Map&lt;String, Integer&gt; counts = countOfAtoms(formula.toCharArray());
        for (String name: counts.keySet()) {
            ans.append(name);
            int count = counts.get(name);
            if (count &gt; 1) ans.append("" + count);
        }
        return ans.toString();
    }
    
    private Map&lt;String, Integer&gt; countOfAtoms(char[] f) {
        Map&lt;String, Integer&gt; ans = new TreeMap&lt;String, Integer&gt;();
        while (i != f.length) {
            if (f[i] == '(') {
                ++i;
                Map&lt;String, Integer&gt; tmp = countOfAtoms(f);
                int count = getCount(f);
                for (Map.Entry&lt;String, Integer&gt; entry : tmp.entrySet())
                    ans.put(entry.getKey(), 
                            ans.getOrDefault(entry.getKey(), 0) 
                            + entry.getValue() * count);
            } else if (f[i] == ')') {
                ++i;
                return ans;
            } else {
                String name = getName(f);
                ans.put(name, ans.getOrDefault(name, 0) + getCount(f));
            }
        }
        return ans;
    }
    
    private String getName(char[] f) {
        String name = "" + f[i++];
        while (i &lt; f.length &amp;&amp; 'a' &lt;= f[i] &amp;&amp; f[i] &lt;= 'z') name += f[i++];
        return name;
    }
    
    private int getCount(char[] f) {
        int count = 0;
        while (i &lt; f.length &amp;&amp; '0' &lt;= f[i] &amp;&amp; f[i] &lt;= '9') {
            count = count * 10 + (f[i] - '0');
            ++i;
        }
        return count == 0 ? 1 : count;
    }
}</pre><p>&nbsp;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/string/leetcode-726-number-of-atoms/">花花酱 LeetCode 726. Number of Atoms</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/string/leetcode-726-number-of-atoms/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
