<?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>combination Archives - Huahua&#039;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/tag/combination/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog/tag/combination/</link>
	<description></description>
	<lastBuildDate>Sat, 05 Feb 2022 02:15:55 +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>combination Archives - Huahua&#039;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog/tag/combination/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>花花酱 LeetCode 2151. Maximum Good People Based on Statements</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-2151-maximum-good-people-based-on-statements/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-2151-maximum-good-people-based-on-statements/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 05 Feb 2022 02:13:31 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[bitmask]]></category>
		<category><![CDATA[combination]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[subsets]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9477</guid>

					<description><![CDATA[<p>There are two types of persons: The&#160;good person: The person who always tells the truth. The&#160;bad person: The person who might tell the truth and&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-2151-maximum-good-people-based-on-statements/">花花酱 LeetCode 2151. Maximum Good People Based on Statements</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>There are two types of persons:</p>



<ul><li>The&nbsp;<strong>good person</strong>: The person who always tells the truth.</li><li>The&nbsp;<strong>bad person</strong>: The person who might tell the truth and might lie.</li></ul>



<p>You are given a&nbsp;<strong>0-indexed</strong>&nbsp;2D integer array&nbsp;<code>statements</code>&nbsp;of size&nbsp;<code>n x n</code>&nbsp;that represents the statements made by&nbsp;<code>n</code>&nbsp;people about each other. More specifically,&nbsp;<code>statements[i][j]</code>&nbsp;could be one of the following:</p>



<ul><li><code>0</code>&nbsp;which represents a statement made by person&nbsp;<code>i</code>&nbsp;that person&nbsp;<code>j</code>&nbsp;is a&nbsp;<strong>bad</strong>&nbsp;person.</li><li><code>1</code>&nbsp;which represents a statement made by person&nbsp;<code>i</code>&nbsp;that person&nbsp;<code>j</code>&nbsp;is a&nbsp;<strong>good</strong>&nbsp;person.</li><li><code>2</code>&nbsp;represents that&nbsp;<strong>no statement</strong>&nbsp;is made by person&nbsp;<code>i</code>&nbsp;about person&nbsp;<code>j</code>.</li></ul>



<p>Additionally, no person ever makes a statement about themselves. Formally, we have that&nbsp;<code>statements[i][i] = 2</code>&nbsp;for all&nbsp;<code>0 &lt;= i &lt; n</code>.</p>



<p>Return&nbsp;<em>the&nbsp;<strong>maximum</strong>&nbsp;number of people who can be&nbsp;<strong>good</strong>&nbsp;based on the statements made by the&nbsp;</em><code>n</code><em>&nbsp;people</em>.</p>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2022/01/15/logic1.jpg" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> statements = [[2,1,2],[1,2,2],[2,0,2]]
<strong>Output:</strong> 2
<strong>Explanation:</strong> Each person makes a single statement.
- Person 0 states that person 1 is good.
- Person 1 states that person 0 is good.
- Person 2 states that person 1 is bad.
Let's take person 2 as the key.
- Assuming that person 2 is a good person:
    - Based on the statement made by person 2, person 1 is a bad person.
    - Now we know for sure that person 1 is bad and person 2 is good.
    - Based on the statement made by person 1, and since person 1 is bad, they could be:
        - telling the truth. There will be a contradiction in this case and this assumption is invalid.
        - lying. In this case, person 0 is also a bad person and lied in their statement.
    - <strong>Following that person 2 is a good person, there will be only one good person in the group</strong>.
- Assuming that person 2 is a bad person:
    - Based on the statement made by person 2, and since person 2 is bad, they could be:
        - telling the truth. Following this scenario, person 0 and 1 are both bad as explained before.
            - <strong>Following that person 2 is bad but told the truth, there will be no good persons in the group</strong>.
        - lying. In this case person 1 is a good person.
            - Since person 1 is a good person, person 0 is also a good person.
            - <strong>Following that person 2 is bad and lied, there will be two good persons in the group</strong>.
We can see that at most 2 persons are good in the best case, so we return 2.
Note that there is more than one way to arrive at this conclusion.
</pre>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2022/01/15/logic2.jpg" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> statements = [[2,0],[0,2]]
<strong>Output:</strong> 1
<strong>Explanation:</strong> Each person makes a single statement.
- Person 0 states that person 1 is bad.
- Person 1 states that person 0 is bad.
Let's take person 0 as the key.
- Assuming that person 0 is a good person:
    - Based on the statement made by person 0, person 1 is a bad person and was lying.
    - <strong>Following that person 0 is a good person, there will be only one good person in the group</strong>.
- Assuming that person 0 is a bad person:
    - Based on the statement made by person 0, and since person 0 is bad, they could be:
        - telling the truth. Following this scenario, person 0 and 1 are both bad.
            - <strong>Following that person 0 is bad but told the truth, there will be no good persons in the group</strong>.
        - lying. In this case person 1 is a good person.
            - <strong>Following that person 0 is bad and lied, there will be only one good person in the group</strong>.
We can see that at most, one person is good in the best case, so we return 1.
Note that there is more than one way to arrive at this conclusion.
</pre>



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



<ul><li><code>n == statements.length == statements[i].length</code></li><li><code>2 &lt;= n &lt;= 15</code></li><li><code>statements[i][j]</code>&nbsp;is either&nbsp;<code>0</code>,&nbsp;<code>1</code>, or&nbsp;<code>2</code>.</li><li><code>statements[i][i] == 2</code></li></ul>



<h2><strong>Solution: Combination / Bitmask</strong></h2>



<p>Enumerate all subsets of n people and assume they are good people. Check whether their statements have any conflicts. We can ignore the statements from bad people since those can be either true or false and does not affect our checks.</p>



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



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

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  int maximumGood(vector&lt;vector&lt;int&gt;&gt;&amp; statements) {
    const int n = statements.size();
    auto valid = [&amp;](int s) {
      for (int i = 0; i &lt; n; ++i) {
        if (!(s &gt;&gt; i &amp; 1)) continue;
        for (int j = 0; j &lt; n; ++j) {
          const bool good = s &gt;&gt; j &amp; 1;
          if ((good &amp;&amp; statements[i][j] == 0) || (!good &amp;&amp; statements[i][j] == 1))
            return false;
        }
      }
      return true;
    };
    int ans = 0;
    for (int s = 1; s &lt; 1 &lt;&lt; n; ++s)
      if (valid(s)) ans = max(ans, __builtin_popcount(s));
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-2151-maximum-good-people-based-on-statements/">花花酱 LeetCode 2151. Maximum Good People Based on Statements</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-2151-maximum-good-people-based-on-statements/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2147. Number of Ways to Divide a Long Corridor</title>
		<link>https://zxi.mytechroad.com/blog/math/leetcode-2147-number-of-ways-to-divide-a-long-corridor/</link>
					<comments>https://zxi.mytechroad.com/blog/math/leetcode-2147-number-of-ways-to-divide-a-long-corridor/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 05 Feb 2022 00:21:58 +0000</pubDate>
				<category><![CDATA[Math]]></category>
		<category><![CDATA[combination]]></category>
		<category><![CDATA[math]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9462</guid>

					<description><![CDATA[<p>Along a long library corridor, there is a line of seats and decorative plants. You are given a&#160;0-indexed&#160;string&#160;corridor&#160;of length&#160;n&#160;consisting of letters&#160;'S'&#160;and&#160;'P'&#160;where each&#160;'S'&#160;represents a seat and&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/math/leetcode-2147-number-of-ways-to-divide-a-long-corridor/">花花酱 LeetCode 2147. Number of Ways to Divide a Long Corridor</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>Along a long library corridor, there is a line of seats and decorative plants. You are given a&nbsp;<strong>0-indexed</strong>&nbsp;string&nbsp;<code>corridor</code>&nbsp;of length&nbsp;<code>n</code>&nbsp;consisting of letters&nbsp;<code>'S'</code>&nbsp;and&nbsp;<code>'P'</code>&nbsp;where each&nbsp;<code>'S'</code>&nbsp;represents a seat and each&nbsp;<code>'P'</code>&nbsp;represents a plant.</p>



<p>One room divider has&nbsp;<strong>already</strong>&nbsp;been installed to the left of index&nbsp;<code>0</code>, and&nbsp;<strong>another</strong>&nbsp;to the right of index&nbsp;<code>n - 1</code>. Additional room dividers can be installed. For each position between indices&nbsp;<code>i - 1</code>&nbsp;and&nbsp;<code>i</code>&nbsp;(<code>1 &lt;= i &lt;= n - 1</code>), at most one divider can be installed.</p>



<p>Divide the corridor into non-overlapping sections, where each section has&nbsp;<strong>exactly two seats</strong>&nbsp;with any number of plants. There may be multiple ways to perform the division. Two ways are&nbsp;<strong>different</strong>&nbsp;if there is a position with a room divider installed in the first way but not in the second way.</p>



<p>Return&nbsp;<em>the number of ways to divide the corridor</em>. Since the answer may be very large, return it&nbsp;<strong>modulo</strong>&nbsp;<code>10<sup>9</sup>&nbsp;+ 7</code>. If there is no way, return&nbsp;<code>0</code>.</p>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2021/12/04/1.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> corridor = "SSPPSPS"
<strong>Output:</strong> 3
<strong>Explanation:</strong> There are 3 different ways to divide the corridor.
The black bars in the above image indicate the two room dividers already installed.
Note that in each of the ways, <strong>each</strong> section has exactly <strong>two</strong> seats.
</pre>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2021/12/04/2.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> corridor = "PPSPSP"
<strong>Output:</strong> 1
<strong>Explanation:</strong> There is only 1 way to divide the corridor, by not installing any additional dividers.
Installing any would create some section that does not have exactly two seats.
</pre>



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



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> corridor = "S"
<strong>Output:</strong> 0
<strong>Explanation:</strong> There is no way to divide the corridor because there will always be a section that does not have exactly two seats.
</pre>



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



<ul><li><code>n == corridor.length</code></li><li><code>1 &lt;= n &lt;= 10<sup>5</sup></code></li><li><code>corridor[i]</code>&nbsp;is either&nbsp;<code>'S'</code>&nbsp;or&nbsp;<code>'P'</code>.</li></ul>



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



<p>If the 2k-th seat is positioned at j, and the 2k+1-th seat is at i. There are (i &#8211; j) ways to split between these two groups.</p>



<p>ans = prod{i<sub>k</sub> &#8211; j<sub>k</sub>}</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">// Author: Huahua
class Solution {
public:
  int numberOfWays(string corridor) {
    constexpr int kMod = 1e9 + 7;
    long ans = 1;
    long k = 0;
    for (long i = 0, j = 0; i &lt; corridor.size(); ++i) {
      if (corridor[i] != 'S') continue;
      if (++k &gt; 2 &amp;&amp; k &amp; 1)
        ans = ans * (i - j) % kMod;
      j = i;
    }
    return (k &gt;= 2 &amp;&amp; k % 2 == 0) ? ans : 0;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/math/leetcode-2147-number-of-ways-to-divide-a-long-corridor/">花花酱 LeetCode 2147. Number of Ways to Divide a Long Corridor</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/math/leetcode-2147-number-of-ways-to-divide-a-long-corridor/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2044. Count Number of Maximum Bitwise-OR Subsets</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-2044-count-number-of-maximum-bitwise-or-subsets/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-2044-count-number-of-maximum-bitwise-or-subsets/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 18 Oct 2021 03:54:32 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[combination]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[subset]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8610</guid>

					<description><![CDATA[<p>Given an integer array&#160;nums, find the&#160;maximum&#160;possible&#160;bitwise OR&#160;of a subset of&#160;nums&#160;and return&#160;the&#160;number of different non-empty subsets&#160;with the maximum bitwise OR. An array&#160;a&#160;is a&#160;subset&#160;of an array&#160;b&#160;if&#160;a&#160;can be&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-2044-count-number-of-maximum-bitwise-or-subsets/">花花酱 LeetCode 2044. Count Number of Maximum Bitwise-OR Subsets</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 integer array&nbsp;<code>nums</code>, find the&nbsp;<strong>maximum</strong>&nbsp;possible&nbsp;<strong>bitwise OR</strong>&nbsp;of a subset of&nbsp;<code>nums</code>&nbsp;and return&nbsp;<em>the&nbsp;<strong>number of different non-empty subsets</strong>&nbsp;with the maximum bitwise OR</em>.</p>



<p>An array&nbsp;<code>a</code>&nbsp;is a&nbsp;<strong>subset</strong>&nbsp;of an array&nbsp;<code>b</code>&nbsp;if&nbsp;<code>a</code>&nbsp;can be obtained from&nbsp;<code>b</code>&nbsp;by deleting some (possibly zero) elements of&nbsp;<code>b</code>. Two subsets are considered&nbsp;<strong>different</strong>&nbsp;if the indices of the elements chosen are different.</p>



<p>The bitwise OR of an array&nbsp;<code>a</code>&nbsp;is equal to&nbsp;<code>a[0]&nbsp;<strong>OR</strong>&nbsp;a[1]&nbsp;<strong>OR</strong>&nbsp;...&nbsp;<strong>OR</strong>&nbsp;a[a.length - 1]</code>&nbsp;(<strong>0-indexed</strong>).</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [3,1]
<strong>Output:</strong> 2
<strong>Explanation:</strong> The maximum possible bitwise OR of a subset is 3. There are 2 subsets with a bitwise OR of 3:
- [3]
- [3,1]
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [2,2,2]
<strong>Output:</strong> 7
<strong>Explanation:</strong> All non-empty subsets of [2,2,2] have a bitwise OR of 2. There are 2<sup>3</sup> - 1 = 7 total subsets.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [3,2,1,5]
<strong>Output:</strong> 6
<strong>Explanation:</strong> The maximum possible bitwise OR of a subset is 7. There are 6 subsets with a bitwise OR of 7:
- [3,5]
- [3,1,5]
- [3,2,5]
- [3,2,1,5]
- [2,5]
- [2,1,5]</pre>



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



<ul><li><code>1 &lt;= nums.length &lt;= 16</code></li><li><code>1 &lt;= nums[i] &lt;= 10<sup>5</sup></code></li></ul>



<h2><strong>Solution: Brute Force</strong></h2>



<p>Try all possible subsets</p>



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



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

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  int countMaxOrSubsets(vector&lt;int&gt;&amp; nums) {
    const int n = nums.size();
    int max_or = 0;
    int count = 0;
    for (int s = 0; s &lt; 1 &lt;&lt; n; ++s) {
      int cur_or = 0;
      for (int i = 0; i &lt; n; ++i)
        if (s &gt;&gt; i &amp; 1) cur_or |= nums[i];
      if (cur_or &gt; max_or) {
        max_or = cur_or;
        count = 1;
      } else if (cur_or == max_or) {
        ++count;
      }
    }
    return count;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-2044-count-number-of-maximum-bitwise-or-subsets/">花花酱 LeetCode 2044. Count Number of Maximum Bitwise-OR Subsets</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-2044-count-number-of-maximum-bitwise-or-subsets/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1879. Minimum XOR Sum of Two Arrays</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1879-minimum-xor-sum-of-two-arrays/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1879-minimum-xor-sum-of-two-arrays/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 07 Aug 2021 07:17:29 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[combination]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[permutation]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8509</guid>

					<description><![CDATA[<p>You are given two integer arrays&#160;nums1&#160;and&#160;nums2&#160;of length&#160;n. The&#160;XOR sum&#160;of the two integer arrays is&#160;(nums1[0] XOR nums2[0]) + (nums1[1] XOR nums2[1]) + ... + (nums1[n -&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1879-minimum-xor-sum-of-two-arrays/">花花酱 LeetCode 1879. Minimum XOR Sum of Two Arrays</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>You are given two integer arrays&nbsp;<code>nums1</code>&nbsp;and&nbsp;<code>nums2</code>&nbsp;of length&nbsp;<code>n</code>.</p>



<p>The&nbsp;<strong>XOR sum</strong>&nbsp;of the two integer arrays is&nbsp;<code>(nums1[0] XOR nums2[0]) + (nums1[1] XOR nums2[1]) + ... + (nums1[n - 1] XOR nums2[n - 1])</code>&nbsp;(<strong>0-indexed</strong>).</p>



<ul><li>For example, the&nbsp;<strong>XOR sum</strong>&nbsp;of&nbsp;<code>[1,2,3]</code>&nbsp;and&nbsp;<code>[3,2,1]</code>&nbsp;is equal to&nbsp;<code>(1 XOR 3) + (2 XOR 2) + (3 XOR 1) = 2 + 0 + 2 = 4</code>.</li></ul>



<p>Rearrange the elements of&nbsp;<code>nums2</code>&nbsp;such that the resulting&nbsp;<strong>XOR sum</strong>&nbsp;is&nbsp;<strong>minimized</strong>.</p>



<p>Return&nbsp;<em>the&nbsp;<strong>XOR sum</strong>&nbsp;after the rearrangement</em>.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums1 = [1,2], nums2 = [2,3]
<strong>Output:</strong> 2
<strong>Explanation:</strong> Rearrange <code>nums2</code> so that it becomes <code>[3,2]</code>.
The XOR sum is (1 XOR 3) + (2 XOR 2) = 2 + 0 = 2.</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums1 = [1,0,3], nums2 = [5,3,4]
<strong>Output:</strong> 8
<strong>Explanation:</strong> Rearrange <code>nums2</code> so that it becomes <code>[5,4,3]</code>. 
The XOR sum is (1 XOR 5) + (0 XOR 4) + (3 XOR 3) = 4 + 4 + 0 = 8.
</pre>



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



<ul><li><code>n == nums1.length</code></li><li><code>n == nums2.length</code></li><li><code>1 &lt;= n &lt;= 14</code></li><li><code>0 &lt;= nums1[i], nums2[i] &lt;= 10<sup>7</sup></code></li></ul>



<h2><strong>Solution: DP / Permutation to combination</strong></h2>



<p>dp[s] := min xor sum by using a subset of nums2 (presented by a binary string s) xor with nums1[0:|s|].</p>



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



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

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  int minimumXORSum(vector&lt;int&gt;&amp; nums1, vector&lt;int&gt;&amp; nums2) {
    const int n = nums1.size();
    vector&lt;int&gt; dp(1 &lt;&lt; n, INT_MAX);
    dp[0] = 0;
    for (int s = 0; s &lt; 1 &lt;&lt; n; ++s) {
      int index = __builtin_popcount(s);
      for (int i = 0; i &lt; n; ++i) {
        if (s &amp; (1 &lt;&lt; i)) continue;
        dp[s | (1 &lt;&lt; i)] = min(dp[s | (1 &lt;&lt; i)],
                               dp[s] + (nums1[index] ^ nums2[i]));
      }
    }    
    return dp.back();
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1879-minimum-xor-sum-of-two-arrays/">花花酱 LeetCode 1879. Minimum XOR Sum of Two Arrays</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/dynamic-programming/leetcode-1879-minimum-xor-sum-of-two-arrays/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1866. Number of Ways to Rearrange Sticks With K Sticks Visible</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1866-number-of-ways-to-rearrange-sticks-with-k-sticks-visible/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1866-number-of-ways-to-rearrange-sticks-with-k-sticks-visible/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Thu, 05 Aug 2021 06:26:50 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[combination]]></category>
		<category><![CDATA[counting]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[hard]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8478</guid>

					<description><![CDATA[<p>There are&#160;n&#160;uniquely-sized sticks whose lengths are integers from&#160;1&#160;to&#160;n. You want to arrange the sticks such that&#160;exactly&#160;k&#160;sticks are&#160;visible&#160;from the left. A stick&#160;is&#160;visible&#160;from the left if there&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1866-number-of-ways-to-rearrange-sticks-with-k-sticks-visible/">花花酱 LeetCode 1866. Number of Ways to Rearrange Sticks With K Sticks Visible</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>There are&nbsp;<code>n</code>&nbsp;uniquely-sized sticks whose lengths are integers from&nbsp;<code>1</code>&nbsp;to&nbsp;<code>n</code>. You want to arrange the sticks such that&nbsp;<strong>exactly</strong>&nbsp;<code>k</code>&nbsp;sticks are&nbsp;<strong>visible</strong>&nbsp;from the left. A stick&nbsp;is&nbsp;<strong>visible</strong>&nbsp;from the left if there are no&nbsp;<strong>longer</strong>&nbsp;sticks to the&nbsp;<strong>left</strong>&nbsp;of it.</p>



<ul><li>For example, if the sticks are arranged&nbsp;<code>[<u>1</u>,<u>3</u>,2,<u>5</u>,4]</code>, then the sticks with lengths&nbsp;<code>1</code>,&nbsp;<code>3</code>, and&nbsp;<code>5</code>&nbsp;are visible from the left.</li></ul>



<p>Given&nbsp;<code>n</code>&nbsp;and&nbsp;<code>k</code>, return&nbsp;<em>the&nbsp;<strong>number</strong>&nbsp;of such arrangements</em>. Since the answer may be large, return it&nbsp;<strong>modulo</strong>&nbsp;<code>10<sup>9</sup>&nbsp;+ 7</code>.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 3, k = 2
<strong>Output:</strong> 3
<strong>Explanation:</strong> [1,3,2], [2,3,1], and [2,1,3] are the only arrangements such that exactly 2 sticks are visible.
The visible sticks are underlined.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 5, k = 5
<strong>Output:</strong> 1
<strong>Explanation:</strong> [1,2,3,4,5] is the only arrangement such that all 5 sticks are visible.
The visible sticks are underlined.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 20, k = 11
<strong>Output:</strong> 647427950
<strong>Explanation:</strong> There are 647427950 (mod 10<sup>9 </sup>+ 7) ways to rearrange the sticks such that exactly 11 sticks are visible.
</pre>



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



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



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



<p>dp(n, k) = dp(n &#8211; 1, k &#8211; 1) + (n-1) * dp(n-1, k)</p>



<p>Time complexity: O(n*k)<br>Space complexity: O(n*k) -&gt; O(k)</p>



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

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  int rearrangeSticks(int n, int k) {
    constexpr int kMod = 1e9 + 7;
    vector&lt;vector&lt;long&gt;&gt; dp(n + 1, vector&lt;long&gt;(k + 1));        
    for (int j = 1; j &lt;= k; ++j) {
      dp[j][j] = 1;
      for (int i = j + 1; i &lt;= n; ++i)
        dp[i][j] = (dp[i - 1][j - 1] + dp[i - 1][j] * (i - 1)) % kMod;
    }
    return dp[n][k];
  }
};</pre>

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

<pre class="crayon-plain-tag"># Author: Huahua
class Solution:
  @lru_cache(maxsize=None)
  def rearrangeSticks(self, n: int, k: int) -&gt; int:
    if k == 0: return 0
    if k == n or n &lt;= 2: return 1
    return (self.rearrangeSticks(n - 1, k - 1) + 
            (n - 1) * self.rearrangeSticks(n - 1, k)) % (10**9 + 7)</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1866-number-of-ways-to-rearrange-sticks-with-k-sticks-visible/">花花酱 LeetCode 1866. Number of Ways to Rearrange Sticks With K Sticks Visible</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/dynamic-programming/leetcode-1866-number-of-ways-to-rearrange-sticks-with-k-sticks-visible/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1815. Maximum Number of Groups Getting Fresh Donuts</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1815-maximum-number-of-groups-getting-fresh-donuts/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1815-maximum-number-of-groups-getting-fresh-donuts/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 05 Apr 2021 07:34:44 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[combination]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[permutation]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8306</guid>

					<description><![CDATA[<p>There is a donuts shop that bakes donuts in batches of&#160;batchSize. They have a rule where they must serve&#160;all&#160;of the donuts of a batch before&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1815-maximum-number-of-groups-getting-fresh-donuts/">花花酱 LeetCode 1815. Maximum Number of Groups Getting Fresh Donuts</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 is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="花花酱 LeetCode 1815. Maximum Number of Groups Getting Fresh Donuts - 刷题找工作 EP391" width="500" height="281" src="https://www.youtube.com/embed/ZpFno2IEHWE?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div></figure>



<p>There is a donuts shop that bakes donuts in batches of&nbsp;<code>batchSize</code>. They have a rule where they must serve&nbsp;<strong>all</strong>&nbsp;of the donuts of a batch before serving any donuts of the next batch. You are given an integer&nbsp;<code>batchSize</code>&nbsp;and an integer array&nbsp;<code>groups</code>, where&nbsp;<code>groups[i]</code>&nbsp;denotes that there is a group of&nbsp;<code>groups[i]</code>&nbsp;customers that will visit the shop. Each customer will get exactly one donut.</p>



<p>When a group visits the shop, all customers of the group must be served before serving any of the following groups. A group will be happy if they all get fresh donuts. That is, the first customer of the group does not receive a donut that was left over from the previous group.</p>



<p>You can freely rearrange the ordering of the groups. Return&nbsp;<em>the&nbsp;<strong>maximum</strong>&nbsp;possible number of happy groups after rearranging the groups.</em></p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> batchSize = 3, groups = [1,2,3,4,5,6]
<strong>Output:</strong> 4
<strong>Explanation:</strong> You can arrange the groups as [6,2,4,5,1,3]. Then the 1<sup>st</sup>, 2<sup>nd</sup>, 4<sup>th</sup>, and 6<sup>th</sup> groups will be happy.
</pre>



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



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



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



<ul><li><code>1 &lt;= batchSize &lt;= 9</code></li><li><code>1 &lt;= groups.length &lt;= 30</code></li><li><code>1 &lt;= groups[i] &lt;= 10<sup>9</sup></code></li></ul>



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



<h2><strong>Solution 0: Binary Mask DP</strong></h2>



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



<p>Time complexity: O(n*2<sup>n</sup>) TLE<br>Space complexity: O(2<sup>n</sup>)</p>



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

<pre class="crayon-plain-tag">// Author: Huahua, TLE, 42/67 Passed
class Solution {
public:
  int maxHappyGroups(int b, vector&lt;int&gt;&amp; groups) {
    const int n = groups.size();
    vector&lt;int&gt; dp(1 &lt;&lt; n);
    for (int mask = 0; mask &lt; 1 &lt;&lt; n; ++mask) {
      int s = 0;
      for (int i = 0; i &lt; n; ++i)
        if (mask &amp; (1 &lt;&lt; i)) s = (s + groups[i]) % b;
      for (int i = 0; i &lt; n; ++i)
        if (!(mask &amp; (1 &lt;&lt; i)))
          dp[mask | (1 &lt;&lt; i)] = max(dp[mask | (1 &lt;&lt; i)],
                                    dp[mask] + (s == 0));
    }
    return dp[(1 &lt;&lt; n) - 1];
  }
};</pre>
</div></div>



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



<figure class="wp-block-image size-large"><a href="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/04/1815-ep391-3.png"><img width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/04/1815-ep391-3.png" alt="" class="wp-image-8316" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/04/1815-ep391-3.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2021/04/1815-ep391-3-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2021/04/1815-ep391-3-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></figure>



<p>State: count of group size % batchSize</p>



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

<pre class="crayon-plain-tag">// Author: Huahua, 888 ms, 61.9 MB
class Solution {
public:
  int maxHappyGroups(int b, vector&lt;int&gt;&amp; groups) {
    int ans = 0;
    vector&lt;int&gt; count(b);
    for (int g : groups) ++count[g % b];      
    map&lt;vector&lt;int&gt;, int&gt; cache;
    function&lt;int(int)&gt; dp = [&amp;](int s) {
      auto it = cache.find(count);
      if (it != cache.end()) return it-&gt;second;
      int ans = 0;
      for (int i = 1; i &lt; b; ++i) {
        if (!count[i]) continue;
        --count[i];
        ans = max(ans, (s == 0) + dp((s + i) % b));
        ++count[i];
      }
      return cache[count] = ans;
    };    
    return count[0] + dp(0);
  }
};</pre>

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

<pre class="crayon-plain-tag">// Author: Huahua 380 ms, 59.2 MB
struct VectorHasher {
  size_t operator()(const vector&lt;int&gt;&amp; V) const {
    size_t hash = V.size();
    for (auto i : V)
      hash ^= i + 0x9e3779b9 + (hash &lt;&lt; 6) + (hash &gt;&gt; 2);
    return hash;
  }
};
class Solution {
public:
  int maxHappyGroups(int b, vector&lt;int&gt;&amp; groups) {
    int ans = 0;
    vector&lt;int&gt; count(b);
    for (int g : groups) ++count[g % b];      
    unordered_map&lt;vector&lt;int&gt;, int, VectorHasher&gt; cache;
    function&lt;int(int)&gt; dp = [&amp;](int s) {
      auto it = cache.find(count);
      if (it != cache.end()) return it-&gt;second;
      int ans = 0;
      for (int i = 1; i &lt; b; ++i) {
        if (!count[i]) continue;
        --count[i];
        ans = max(ans, (s == 0) + dp((s + b - i) % b));
        ++count[i];
      }
      return cache[count] = ans;
    };    
    return count[0] + dp(0);
  }
};</pre>

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

<pre class="crayon-plain-tag">// Author: Huahua, 0 ms, 8.1 MB
class Solution {
public:
  int maxHappyGroups(int b, vector&lt;int&gt;&amp; groups) {
    int ans = 0;
    vector&lt;int&gt; count(b);
    for (int g : groups) {
      const int r = g % b;
      if (r == 0) { ++ans; continue; }      
      if (count[b - r]) {
        --count[b - r];
        ++ans;
      } else {
        ++count[r];
      }
    }    
    map&lt;vector&lt;int&gt;, int&gt; cache;
    function&lt;int(int, int)&gt; dp = [&amp;](int r, int n) {
      if (n == 0) return 0;
      auto it = cache.find(count);
      if (it != cache.end()) return it-&gt;second;
      int ans = 0;
      for (int i = 1; i &lt; b; ++i) {
        if (!count[i]) continue;
        --count[i];
        ans = max(ans, (r == 0) + dp((r + b - i) % b, n - 1));
        ++count[i];
      }
      return cache[count] = ans;
    };
    const int n = accumulate(begin(count), end(count), 0);
    return ans + (n ? dp(0, n) : 0);
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1815-maximum-number-of-groups-getting-fresh-donuts/">花花酱 LeetCode 1815. Maximum Number of Groups Getting Fresh Donuts</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/dynamic-programming/leetcode-1815-maximum-number-of-groups-getting-fresh-donuts/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1286. Iterator for Combination</title>
		<link>https://zxi.mytechroad.com/blog/bit/leetcode-1286-iterator-for-combination/</link>
					<comments>https://zxi.mytechroad.com/blog/bit/leetcode-1286-iterator-for-combination/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 30 Nov 2020 08:09:26 +0000</pubDate>
				<category><![CDATA[Bit]]></category>
		<category><![CDATA[combination]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[string]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7748</guid>

					<description><![CDATA[<p>Design an Iterator class, which has: A constructor that takes a string&#160;characters&#160;of&#160;sorted distinct&#160;lowercase English letters and a number&#160;combinationLength&#160;as arguments. A function&#160;next()&#160;that returns the next combination&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/bit/leetcode-1286-iterator-for-combination/">花花酱 LeetCode 1286. Iterator for Combination</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Design an Iterator class, which has:</p>



<ul><li>A constructor that takes a string&nbsp;<code>characters</code>&nbsp;of&nbsp;<strong>sorted distinct</strong>&nbsp;lowercase English letters and a number&nbsp;<code>combinationLength</code>&nbsp;as arguments.</li><li>A function&nbsp;<em>next()</em>&nbsp;that returns the next combination of length&nbsp;<code>combinationLength</code>&nbsp;in&nbsp;<strong>lexicographical order</strong>.</li><li>A function&nbsp;<em>hasNext()</em>&nbsp;that returns&nbsp;<code>True</code>&nbsp;if and only if&nbsp;there exists a next combination.</li></ul>



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



<pre class="wp-block-preformatted;crayon:false">CombinationIterator iterator = new CombinationIterator("abc", 2); // creates the iterator.

iterator.next(); // returns "ab"
iterator.hasNext(); // returns true
iterator.next(); // returns "ac"
iterator.hasNext(); // returns true
iterator.next(); // returns "bc"
iterator.hasNext(); // returns false
</pre>



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



<ul><li><code>1 &lt;= combinationLength &lt;=&nbsp;characters.length &lt;= 15</code></li><li>There will be at most&nbsp;<code>10^4</code>&nbsp;function calls per test.</li><li>It&#8217;s guaranteed that all&nbsp;calls&nbsp;of the function&nbsp;<code>next</code>&nbsp;are valid.</li></ul>



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



<p>Use a bitmask to represent the chars selected.<br>start with (2^n &#8211; 1), decrease the mask until there are c bit set.<br>stop when mask reach to 0.</p>



<p>mask: 111 =&gt; abc<br>mask: 110 =&gt; ab<br>mask: 101 =&gt; ac<br>mask: 011 =&gt; bc<br>mask: 000 =&gt; &#8220;&#8221; Done</p>



<p>Time complexity: O(2^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 CombinationIterator {
public:
  CombinationIterator(string characters, int combinationLength): 
    chars_(rbegin(characters), rend(characters)),
    length_(combinationLength),
    mask_((1 &lt;&lt; characters.size()) - 1) {}

  string next() {
    hasNext();    
    string ans;
    for (int i = chars_.size() - 1; i &gt;= 0 ; --i)
      if ((mask_ &gt;&gt; i) &amp; 1)
        ans.push_back(chars_[i]);
    --mask_;
    return ans;
  }

  bool hasNext() {
    while (mask_ &gt;= 0 &amp;&amp; __builtin_popcount(mask_) != length_) --mask_;
    return mask_ &gt; 0;
  }
private:
  int mask_ = 0;  
  const int length_;
  const string chars_;
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/bit/leetcode-1286-iterator-for-combination/">花花酱 LeetCode 1286. Iterator for Combination</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/bit/leetcode-1286-iterator-for-combination/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1621. Number of Sets of K Non-Overlapping Line Segments</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1621-number-of-sets-of-k-non-overlapping-line-segments/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1621-number-of-sets-of-k-non-overlapping-line-segments/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 17 Oct 2020 21:50:56 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[combination]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[medium]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7519</guid>

					<description><![CDATA[<p>Given&#160;n&#160;points on a 1-D plane, where the&#160;ith&#160;point (from&#160;0&#160;to&#160;n-1) is at&#160;x = i, find the number of ways we can draw&#160;exactly&#160;k&#160;non-overlapping&#160;line segments such that each segment&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1621-number-of-sets-of-k-non-overlapping-line-segments/">花花酱 LeetCode 1621. Number of Sets of K Non-Overlapping Line Segments</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="花花酱 LeetCode 1621. Number of Sets of K Non-Overlapping Line Segments - 刷题找工作 EP363" width="500" height="281" src="https://www.youtube.com/embed/AJoe3EXyYLc?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div></figure>



<p>Given&nbsp;<code>n</code>&nbsp;points on a 1-D plane, where the&nbsp;<code>i<sup>th</sup></code>&nbsp;point (from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>n-1</code>) is at&nbsp;<code>x = i</code>, find the number of ways we can draw&nbsp;<strong>exactly</strong>&nbsp;<code>k</code>&nbsp;<strong>non-overlapping</strong>&nbsp;line segments such that each segment covers two or more points. The endpoints of each segment must have&nbsp;<strong>integral coordinates</strong>. The&nbsp;<code>k</code>&nbsp;line segments&nbsp;<strong>do not</strong>&nbsp;have to cover all&nbsp;<code>n</code>&nbsp;points, and they are&nbsp;<strong>allowed</strong>&nbsp;to share endpoints.</p>



<p>Return&nbsp;<em>the number of ways we can draw&nbsp;</em><code>k</code><em>&nbsp;non-overlapping line segments</em><em>.</em>&nbsp;Since this number can be huge, return it&nbsp;<strong>modulo</strong>&nbsp;<code>10<sup>9</sup>&nbsp;+ 7</code>.</p>



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



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 4, k = 2
<strong>Output:</strong> 5
<strong>Explanation: 
</strong>The two line segments are shown in red and blue.
The image above shows the 5 different ways {(0,2),(2,3)}, {(0,1),(1,3)}, {(0,1),(2,3)}, {(1,2),(2,3)}, {(0,1),(1,2)}.</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 3, k = 1
<strong>Output:</strong> 3
<strong>Explanation: </strong>The 3 ways are {(0,1)}, {(0,2)}, {(1,2)}.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 30, k = 7
<strong>Output:</strong> 796297179
<strong>Explanation: </strong>The total number of possible ways to draw 7 line segments is 3796297200. Taking this number modulo 10<sup>9</sup> + 7 gives us 796297179.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 5, k = 3
<strong>Output:</strong> 7
</pre>



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



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



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



<ul><li><code>2 &lt;= n &lt;= 1000</code></li><li><code>1 &lt;= k &lt;= n-1</code></li></ul>



<h2><strong>Solution 1: Naive DP (TLE)</strong></h2>



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



<p>dp[n][k] := ans of problem(n, k)<br>dp[n][1] = n * (n &#8211; 1) / 2   # C(n,2)<br>dp[n][k] = 1 if k == n &#8211; 1<br>dp[n][k] = 0 if k &gt;= n<br>dp[n][k] = sum((i &#8211; 1) * dp(n &#8211; i + 1, k &#8211; 1) 2 &lt;= i &lt; n</p>



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



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

<pre class="crayon-plain-tag">class Solution {
public:
  int numberOfSets(int n, int k) {
    constexpr int kMod = 1e9 + 7;
    vector&lt;vector&lt;int&gt;&gt; cache(n + 1, vector&lt;int&gt;(k + 1));
    function&lt;int(int, int)&gt; dp = [&amp;](int n, int k) {
      if (k &gt;= n) return 0;
      if (k == 1) return n * (n - 1) / 2;
      if (k == n - 1) return 1;      
      int&amp; ans = cache[n][k];
      if (ans) return ans;
      for (long i = 2; i &lt; n; ++i) {
        const int t = ((i - 1) * dp(n - i + 1, k - 1)) % kMod;
        ans = (ans + t) % kMod;
      }     
      return ans;
    };
    return dp(n, k);
  }
};</pre>
</div></div>



<h2><strong>Solution 2: DP w/ Prefix Sum</strong></h2>



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



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



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

<pre class="crayon-plain-tag"># Author: Huahua 940 ms
class Solution:
  def numberOfSets(self, n: int, k: int) -&gt; int:
    kMod = 10**9 + 7
    dp = [[0] * (k + 1) for _ in range(n + 1)]
    
    for i in range(n + 1):
      dp[i][0] = 1
      
    for j in range(1, k + 1):
      s = 0
      for i in range(1, n + 1):        
        dp[i][j] = (s + dp[i - 1][j])
        s += dp[i][j - 1]
    return dp[n][k] % kMod</pre>
</div></div>



<h2><strong>Solution 3: DP / 3D State</strong></h2>



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



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



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

<pre class="crayon-plain-tag"># Author: Huahua 940 ms
class Solution:
  def numberOfSets(self, n: int, k: int) -&gt; int:    
    kMod = 10**9 + 7
    
    @lru_cache(None)
    def dp(n: int, k: int, e: int) -&gt; int: 
      if k == 0: return 1
      if k &gt; n: return 0
      return (dp(n - 1, k, e) + dp(n + e - 1, k - e, 1 - e)) % kMod
    return dp(n, k, 0)</pre>
</div></div>



<p></p>



<h2><strong>Solution 4: DP / Mathematical induction</strong></h2>



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



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



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



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

<pre class="crayon-plain-tag"># Author: Huahua 648 ms
class Solution:
  def numberOfSets(self, n: int, k: int) -&gt; int:        
    @lru_cache(None)
    def dp(n: int, k: int) -&gt; int: 
      if k &gt;= n: return 0
      if k == 1: return n * (n - 1) // 2
      if k == n - 1: return 1
      return 2 * dp(n - 1, k) - dp(n - 2, k) + dp(n - 1, k - 1)
    
    return dp(n, k) % (10**9 + 7)</pre>
</div></div>



<p></p>



<h2><strong>Solution 5: DP / Reduction</strong></h2>



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



<p>This problem can be reduced to: given n + k &#8211; 1 points, pick k segments (2*k points). <br>if two consecutive points were selected by two segments e.g. i for A and i+1 for B, then they share a point in the original space. <br>Answer C(n + k &#8211; 1, 2*k)</p>



<p>Time complexity: O((n+k)*2) Pascal&#8217;s triangle<br>Space complexity: O((n+k)*2)</p>



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

<pre class="crayon-plain-tag">class Solution {
public:
  int numberOfSets(int n, int k) {
    constexpr int kMod = 1e9 + 7;
    vector&lt;vector&lt;int&gt;&gt; dp(n + k , vector&lt;int&gt;(n + k));
    for (int i = 0; i &lt; n + k; ++i) {
      dp[i][0] = dp[i][i] = 1;
      for (int j = 1; j &lt; i; ++j)
        dp[i][j] = (dp[i - 1][j - 1] + dp[i - 1][j]) % kMod;
    }
    return dp[n + k - 1][2 * k];
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1621-number-of-sets-of-k-non-overlapping-line-segments/">花花酱 LeetCode 1621. Number of Sets of K Non-Overlapping Line Segments</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/dynamic-programming/leetcode-1621-number-of-sets-of-k-non-overlapping-line-segments/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1601. Maximum Number of Achievable Transfer Requests</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-1601-maximum-number-of-achievable-transfer-requests/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-1601-maximum-number-of-achievable-transfer-requests/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 27 Sep 2020 18:19:02 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[combination]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[search]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7429</guid>

					<description><![CDATA[<p>We have&#160;n&#160;buildings numbered from&#160;0&#160;to&#160;n - 1. Each building has a number of employees. It&#8217;s transfer season, and some employees want to change the building they&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-1601-maximum-number-of-achievable-transfer-requests/">花花酱 LeetCode 1601. Maximum Number of Achievable Transfer Requests</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>We have&nbsp;<code>n</code>&nbsp;buildings numbered from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>n - 1</code>. Each building has a number of employees. It&#8217;s transfer season, and some employees want to change the building they reside in.</p>



<p>You are given an array&nbsp;<code>requests</code>&nbsp;where&nbsp;<code>requests[i] = [from<sub>i</sub>, to<sub>i</sub>]</code>&nbsp;represents an employee&#8217;s request to transfer from building&nbsp;<code>from<sub>i</sub></code>&nbsp;to building&nbsp;<code>to<sub>i</sub></code>.</p>



<p><strong>All buildings are full</strong>, so a list of requests is achievable only if for each building, the&nbsp;<strong>net change in employee transfers is zero</strong>. This means the number of employees&nbsp;<strong>leaving</strong>&nbsp;is&nbsp;<strong>equal</strong>&nbsp;to the number of employees&nbsp;<strong>moving in</strong>. For example if&nbsp;<code>n = 3</code>&nbsp;and two employees are leaving building&nbsp;<code>0</code>, one is leaving building&nbsp;<code>1</code>, and one is leaving building&nbsp;<code>2</code>, there should be two employees moving to building&nbsp;<code>0</code>, one employee moving to building&nbsp;<code>1</code>, and one employee moving to building&nbsp;<code>2</code>.</p>



<p>Return&nbsp;<em>the maximum number of achievable requests</em>.</p>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2020/09/10/move1.jpg" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 5, requests = [[0,1],[1,0],[0,1],[1,2],[2,0],[3,4]]
<strong>Output:</strong> 5
<strong>Explantion:</strong> Let's see the requests:
From building 0 we have employees x and y and both want to move to building 1.
From building 1 we have employees a and b and they want to move to buildings 2 and 0 respectively.
From building 2 we have employee z and they want to move to building 0.
From building 3 we have employee c and they want to move to building 4.
From building 4 we don't have any requests.
We can achieve the requests of users x and b by swapping their places.
We can achieve the requests of users y, a and z by swapping the places in the 3 buildings.
</pre>



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



<figure class="wp-block-image"><img src="https://assets.leetcode.com/uploads/2020/09/10/move2.jpg" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 3, requests = [[0,0],[1,2],[2,1]]
<strong>Output:</strong> 3
<strong>Explantion:</strong> Let's see the requests:
From building 0 we have employee x and they want to stay in the same building 0.
From building 1 we have employee y and they want to move to building 2.
From building 2 we have employee z and they want to move to building 1.
We can achieve all the requests. </pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 4, requests = [[0,3],[3,1],[1,2],[2,0]]
<strong>Output:</strong> 4
</pre>



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



<ul><li><code>1 &lt;= n &lt;= 20</code></li><li><code>1 &lt;= requests.length &lt;= 16</code></li><li><code>requests[i].length == 2</code></li><li><code>0 &lt;= from<sub>i</sub>, to<sub>i</sub>&nbsp;&lt; n</code></li></ul>



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



<p>Try all combinations: O(2^n * (r + 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 maximumRequests(int n, vector&lt;vector&lt;int&gt;&gt;&amp; requests) {
    const int r = requests.size(); 
    int ans = 0;
    vector&lt;int&gt; nets(n);
    for (int s = 0; s &lt; 1 &lt;&lt; r; ++s) {
      fill(begin(nets), end(nets), 0);
      for (int j = 0; j &lt; r; ++j)
        if (s &amp; (1 &lt;&lt; j)) {
          --nets[requests[j][0]];
          ++nets[requests[j][1]];
        }
      if (all_of(begin(nets), end(nets), [](const int x) { return x == 0; }))
        ans = max(ans, __builtin_popcount(s));
    }
    return ans;
  }
};</pre>

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

<pre class="crayon-plain-tag"># Author: Huahua
class Solution:
  def maximumRequests(self, n: int, requests: List[List[int]]) -&gt; int:
    r = len(requests)
    ans = 0
    for s in range(1 &lt;&lt; r):
      degrees = [0] * n
      for i in range(r):
        if s &amp; (1 &lt;&lt; i):
          degrees[requests[i][0]] -= 1
          degrees[requests[i][1]] += 1
      if not any(degrees):
        ans = max(ans, bin(s).count('1'))
    return ans</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-1601-maximum-number-of-achievable-transfer-requests/">花花酱 LeetCode 1601. Maximum Number of Achievable Transfer Requests</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-1601-maximum-number-of-achievable-transfer-requests/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1593. Split a String Into the Max Number of Unique Substrings</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-1593-split-a-string-into-the-max-number-of-unique-substrings/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-1593-split-a-string-into-the-max-number-of-unique-substrings/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 21 Sep 2020 07:16:43 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[combination]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[search]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7402</guid>

					<description><![CDATA[<p>Given a string&#160;s,&#160;return&#160;the maximum&#160;number of unique substrings that the given string can be split into. You can split string&#160;s&#160;into any list of&#160;non-empty substrings, where the&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-1593-split-a-string-into-the-max-number-of-unique-substrings/">花花酱 LeetCode 1593. Split a String Into the Max Number of Unique Substrings</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="花花酱 LeetCode 1593. Split a String Into the Max Number of Unique Substrings - 刷题找工作 EP357" width="500" height="281" src="https://www.youtube.com/embed/VEdqP8rXfAc?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div></figure>



<p>Given a string&nbsp;<code>s</code>,&nbsp;return&nbsp;<em>the maximum&nbsp;number of unique substrings that the given string can be split into</em>.</p>



<p>You can split string&nbsp;<code>s</code>&nbsp;into any list of&nbsp;<strong>non-empty substrings</strong>, where the concatenation of the substrings forms the original string.&nbsp;However, you must split the substrings such that all of them are&nbsp;<strong>unique</strong>.</p>



<p>A&nbsp;<strong>substring</strong>&nbsp;is a contiguous sequence of characters within a string.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "ababccc"
<strong>Output:</strong> 5
<strong>Explanation</strong>: One way to split maximally is ['a', 'b', 'ab', 'c', 'cc']. Splitting like ['a', 'b', 'a', 'b', 'c', 'cc'] is not valid as you have 'a' and 'b' multiple times.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "aba"
<strong>Output:</strong> 2
<strong>Explanation</strong>: One way to split maximally is ['a', 'ba'].
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "aa"
<strong>Output:</strong> 1
<strong>Explanation</strong>: It is impossible to split the string any further.
</pre>



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



<ul><li><code>1 &lt;= s.length&nbsp;&lt;= 16</code></li><li><code>s</code>&nbsp;contains&nbsp;only lower case English letters.</li></ul>



<h2><strong>Solution: Brute Force</strong></h2>



<p>Try all combinations.<br>Time complexity: O(2^n)<br>Space complexity: O(n)</p>



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

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  int maxUniqueSplit(string_view s) {
    const int n = s.length();
    if (n == 1) return 1;
    size_t ans = 1;
    unordered_set&lt;string_view&gt; seen;
    for (int m = 1; m &lt; 1 &lt;&lt; (n - 1); ++m) {
      if (__builtin_popcount(m) &lt; ans) continue; // 956 ms -&gt; 52 ms
      bool valid = true;
      int p = 0;
      for (int i = 1; i &lt;= n &amp;&amp; valid; ++i) {
        if (m &amp; (1 &lt;&lt; (i - 1)) || i == n) {
          valid &amp;= seen.insert(s.substr(p, i - p)).second;
          p = i;
        }
      }
      if (valid) ans = max(ans, seen.size());
      seen.clear();
    }
    return ans;
  }
};</pre>

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

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  int maxUniqueSplit(string_view s) {
    size_t ans = 1;
    const int n = s.length();
    unordered_set&lt;string_view&gt; seen;
    function&lt;void(int)&gt; dfs = [&amp;](int p) {
      if (p == n) {        
        ans = max(ans, seen.size());
        return;
      }
      for (int i = p; i &lt; n; ++i) {
        string_view ss = s.substr(p, i - p + 1);
        if (!seen.insert(ss).second) continue;
        dfs(i + 1);
        seen.erase(ss);
      }
    };
    dfs(0);
    return ans;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-1593-split-a-string-into-the-max-number-of-unique-substrings/">花花酱 LeetCode 1593. Split a String Into the Max Number of Unique Substrings</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-1593-split-a-string-into-the-max-number-of-unique-substrings/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1577. Number of Ways Where Square of Number Is Equal to Product of Two Numbers</title>
		<link>https://zxi.mytechroad.com/blog/hashtable/leetcode-1577-number-of-ways-where-square-of-number-is-equal-to-product-of-two-numbers/</link>
					<comments>https://zxi.mytechroad.com/blog/hashtable/leetcode-1577-number-of-ways-where-square-of-number-is-equal-to-product-of-two-numbers/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 06 Sep 2020 05:05:47 +0000</pubDate>
				<category><![CDATA[Hashtable]]></category>
		<category><![CDATA[combination]]></category>
		<category><![CDATA[frequency]]></category>
		<category><![CDATA[hashtable]]></category>
		<category><![CDATA[medium]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7348</guid>

					<description><![CDATA[<p>Given two arrays of integers&#160;nums1&#160;and&#160;nums2, return the number of triplets formed (type 1 and type 2) under the following rules: Type 1: Triplet (i, j,&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/hashtable/leetcode-1577-number-of-ways-where-square-of-number-is-equal-to-product-of-two-numbers/">花花酱 LeetCode 1577. Number of Ways Where Square of Number Is Equal to Product of Two Numbers</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 two arrays of integers&nbsp;<code>nums1</code>&nbsp;and&nbsp;<code>nums2</code>, return the number of triplets formed (type 1 and type 2) under the following rules:</p>



<ul><li>Type 1: Triplet (i, j, k)&nbsp;if&nbsp;<code>nums1[i]<sup>2</sup>&nbsp;== nums2[j] * nums2[k]</code>&nbsp;where&nbsp;<code>0 &lt;= i &lt; nums1.length</code>&nbsp;and&nbsp;<code>0 &lt;= j &lt; k &lt; nums2.length</code>.</li><li>Type 2:&nbsp;Triplet (i, j, k) if&nbsp;<code>nums2[i]<sup>2</sup>&nbsp;== nums1[j] * nums1[k]</code>&nbsp;where&nbsp;<code>0 &lt;= i &lt; nums2.length</code>&nbsp;and&nbsp;<code>0 &lt;= j &lt; k &lt; nums1.length</code>.</li></ul>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums1 = [7,4], nums2 = [5,2,8,9]
<strong>Output:</strong> 1
<strong>Explanation:</strong> Type 1: (1,1,2), nums1[1]^2 = nums2[1] * nums2[2]. (4^2 = 2 * 8). 
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums1 = [1,1], nums2 = [1,1,1]
<strong>Output:</strong> 9
<strong>Explanation:</strong> All Triplets are valid, because 1^2 = 1 * 1.
Type 1: (0,0,1), (0,0,2), (0,1,2), (1,0,1), (1,0,2), (1,1,2).  nums1[i]^2 = nums2[j] * nums2[k].
Type 2: (0,0,1), (1,0,1), (2,0,1). nums2[i]^2 = nums1[j] * nums1[k].
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums1 = [7,7,8,3], nums2 = [1,2,9,7]
<strong>Output:</strong> 2
<strong>Explanation:</strong> There are 2 valid triplets.
Type 1: (3,0,2).  nums1[3]^2 = nums2[0] * nums2[2].
Type 2: (3,0,1).  nums2[3]^2 = nums1[0] * nums1[1].
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums1 = [4,7,9,11,23], nums2 = [3,5,1024,12,18]
<strong>Output:</strong> 0
<strong>Explanation:</strong> There are no valid triplets.
</pre>



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



<ul><li><code>1 &lt;= nums1.length, nums2.length &lt;= 1000</code></li><li><code>1 &lt;= nums1[i], nums2[i] &lt;= 10^5</code></li></ul>



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



<p>For each number y in the second array, count its frequency.</p>



<p>For each number x in the first, if x * x % y == 0, let r = x * x / y<br>if r == y: ans += f[y] * f[y-1]<br>else ans += f[y] * f[r]<br><br>Final ans /= 2</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 numTriplets(vector&lt;int&gt;&amp; nums1, vector&lt;int&gt;&amp; nums2) {
    return solve(nums1, nums2) + solve(nums2, nums1);
  }
private:
  int solve(vector&lt;int&gt;&amp; nums1, vector&lt;int&gt;&amp; nums2) {
    int ans = 0;
    unordered_map&lt;int, int&gt; f;
    for (int y : nums2) ++f[y];
    for (long x : nums1)
      for (const auto&amp; [y, c] : f) {                
        long r = x * x / y;
        if (x * x % y || !f.count(r)) continue;
        if (r == y) ans += c * (c - 1);
        else ans += c * f[r];
      }
    return ans / 2;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/hashtable/leetcode-1577-number-of-ways-where-square-of-number-is-equal-to-product-of-two-numbers/">花花酱 LeetCode 1577. Number of Ways Where Square of Number Is Equal to Product of Two Numbers</a> appeared first on <a rel="nofollow" href="https://zxi.mytechroad.com/blog">Huahua&#039;s Tech Road</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/hashtable/leetcode-1577-number-of-ways-where-square-of-number-is-equal-to-product-of-two-numbers/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1573. Number of Ways to Split a String</title>
		<link>https://zxi.mytechroad.com/blog/math/leetcode-1573-number-of-ways-to-split-a-string/</link>
					<comments>https://zxi.mytechroad.com/blog/math/leetcode-1573-number-of-ways-to-split-a-string/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 05 Sep 2020 18:29:04 +0000</pubDate>
				<category><![CDATA[Math]]></category>
		<category><![CDATA[combination]]></category>
		<category><![CDATA[math]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7330</guid>

					<description><![CDATA[<p>Given a binary string&#160;s&#160;(a string consisting only of &#8216;0&#8217;s and &#8216;1&#8217;s),&#160;we can split&#160;s&#160;into 3&#160;non-empty&#160;strings s1, s2, s3 (s1+ s2+ s3 = s). Return the number&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/math/leetcode-1573-number-of-ways-to-split-a-string/">花花酱 LeetCode 1573. Number of Ways to Split a 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[
<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 1573. Number of Ways to Split a String - 刷题找工作 EP354" width="500" height="281" src="https://www.youtube.com/embed/gkFKRbkrIws?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div></figure>



<p>Given a binary string&nbsp;<code>s</code>&nbsp;(a string consisting only of &#8216;0&#8217;s and &#8216;1&#8217;s),&nbsp;we can split&nbsp;<code>s</code>&nbsp;into 3&nbsp;<strong>non-empty</strong>&nbsp;strings s1, s2, s3 (s1+ s2+ s3 = s).</p>



<p>Return the number of ways&nbsp;<code>s</code>&nbsp;can be split such that the number of&nbsp;characters &#8216;1&#8217; is the same in s1, s2, and s3.</p>



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



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "10101"
<strong>Output:</strong> 4
<strong>Explanation:</strong> There are four ways to split s in 3 parts where each part contain the same number of letters '1'.
"1|010|1"
"1|01|01"
"10|10|1"
"10|1|01"
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "1001"
<strong>Output:</strong> 0
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "0000"
<strong>Output:</strong> 3
<strong>Explanation:</strong> There are three ways to split s in 3 parts.
"0|0|00"
"0|00|0"
"00|0|0"
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "100100010100110"
<strong>Output:</strong> 12
</pre>



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



<ul><li><code>s[i] == '0'</code>&nbsp;or&nbsp;<code>s[i] == '1'</code></li><li><code>3 &lt;= s.length &lt;= 10^5</code></li></ul>



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



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



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



<p>Count how many ones in the binary string as T, if not a factor of 3, then there is no answer.</p>



<p>Count how many positions that have prefix sum of T/3 as l, and how many positions that have prefix sum of T/3*2 as r.</p>



<p>Ans = l * r</p>



<p>But we need to special handle the all zero cases, which equals to C(n-2, 2) = (n &#8211; 1) * (n &#8211; 2) / 2</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 numWays(string s) {
    const int kMod = 1e9 + 7;
    const long n = s.length();
    int t = 0;
    for (char c : s) t += c == '1';
    if (t % 3) return 0;
    if (t == 0)
      return ((1 + (n - 2)) * (n - 2) / 2) % kMod;
    t /= 3;
    long l = 0;
    long r = 0;
    for (int i = 0, c = 0; i &lt; n; ++i) {
      c += (s[i] == '1');
      if (c == t) ++l;
      else if (c == t * 2) ++r;
    }
    return (l * r) % kMod;
  }
};</pre>

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

<pre class="crayon-plain-tag">class Solution:
  def numWays(self, s: str) -&gt; int:
    n = len(s)
    t = s.count('1')
    if t % 3 != 0: return 0
    if t == 0: return ((n - 1) * (n - 2) // 2) % (10**9 + 7)
    t //= 3
    l, r, c = 0, 0, 0
    for i, ch in enumerate(s):
      if ch == '1': c += 1
      if c == t: l += 1
      elif c == t * 2: r += 1
    return (l * r) % (10**9 + 7)</pre>
</div></div>



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



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

<pre class="crayon-plain-tag">class Solution:
  def numWays(self, s: str) -&gt; int:
    n = len(s)
    p = defaultdict(int)
    c = 0
    for ch in s:
      if ch == '1': c += 1
      p[c] += 1
    if c % 3 != 0: return 0
    if c == 0: return ((n - 1) * (n - 2) // 2) % (10**9 + 7)
    return (p[c // 3] * p[c // 3 * 2]) % (10**9 + 7)</pre>
</div></div>

<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/math/leetcode-1573-number-of-ways-to-split-a-string/">花花酱 LeetCode 1573. Number of Ways to Split a 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/math/leetcode-1573-number-of-ways-to-split-a-string/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 1467. Probability of a Two Boxes Having The Same Number of Distinct Balls</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-1467-probability-of-a-two-boxes-having-the-same-number-of-distinct-balls/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-1467-probability-of-a-two-boxes-having-the-same-number-of-distinct-balls/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Thu, 04 Jun 2020 05:18:59 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[combination]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[permutation]]></category>
		<category><![CDATA[probability]]></category>
		<category><![CDATA[search]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=6867</guid>

					<description><![CDATA[<p>Given&#160;2n&#160;balls of&#160;k&#160;distinct colors. You will be given an integer array&#160;balls&#160;of size&#160;k&#160;where&#160;balls[i]&#160;is the number of balls of color&#160;i.&#160; All the balls will be&#160;shuffled uniformly at random,&#160;then&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-1467-probability-of-a-two-boxes-having-the-same-number-of-distinct-balls/">花花酱 LeetCode 1467. Probability of a Two Boxes Having The Same Number of Distinct Balls</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 title="花花酱 LeetCode 1467. Probability of a Two Boxes Having The Same Number of Distinct Balls - 刷题找工作 EP332" width="500" height="375" src="https://www.youtube.com/embed/EZS6E6swOsY?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div></figure>



<p>Given&nbsp;<code>2n</code>&nbsp;balls of&nbsp;<code>k</code>&nbsp;distinct colors. You will be given an integer array&nbsp;<code>balls</code>&nbsp;of size&nbsp;<code>k</code>&nbsp;where&nbsp;<code>balls[i]</code>&nbsp;is the number of balls of color&nbsp;<code>i</code>.&nbsp;</p>



<p>All the balls will be&nbsp;<strong>shuffled uniformly at random</strong>,&nbsp;then we will distribute the first&nbsp;<code>n</code>&nbsp;balls to the first box and the remaining&nbsp;<code>n</code>&nbsp;balls to the other box (Please read the explanation of the second example carefully).</p>



<p>Please note that the two boxes are considered different. For example, if we have two balls of colors&nbsp;<code>a</code>&nbsp;and&nbsp;<code>b</code>, and two boxes&nbsp;<code>[]</code>&nbsp;and&nbsp;<code>()</code>, then the distribution&nbsp;<code>[a] (b)</code>&nbsp;is considered different than the distribution&nbsp;<code>[b] (a)&nbsp;</code>(Please read the explanation of the first&nbsp;example carefully).</p>



<p>We want to&nbsp;<em>calculate the probability</em>&nbsp;that the two boxes have the same number of distinct balls.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> balls = [1,1]
<strong>Output:</strong> 1.00000
<strong>Explanation:</strong> Only 2 ways to divide the balls equally:
- A ball of color 1 to box 1 and a ball of color 2 to box 2
- A ball of color 2 to box 1 and a ball of color 1 to box 2
In both ways, the number of distinct colors in each box is equal. The probability is 2/2 = 1
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> balls = [2,1,1]
<strong>Output:</strong> 0.66667
<strong>Explanation:</strong> We have the set of balls [1, 1, 2, 3]
This set of balls will be shuffled randomly and we may have one of the 12 distinct shuffles with equale probability (i.e. 1/12):
[1,1 / 2,3], [1,1 / 3,2], [1,2 / 1,3], [1,2 / 3,1], [1,3 / 1,2], [1,3 / 2,1], [2,1 / 1,3], [2,1 / 3,1], [2,3 / 1,1], [3,1 / 1,2], [3,1 / 2,1], [3,2 / 1,1]
After that we add the first two balls to the first box and the second two balls to the second box.
We can see that 8 of these 12 possible random distributions have the same number of distinct colors of balls in each box.
Probability is 8/12 = 0.66667
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> balls = [1,2,1,2]
<strong>Output:</strong> 0.60000
<strong>Explanation:</strong> The set of balls is [1, 2, 2, 3, 4, 4]. It is hard to display all the 180 possible random shuffles of this set but it is easy to check that 108 of them will have the same number of distinct colors in each box.
Probability = 108 / 180 = 0.6
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> balls = [3,2,1]
<strong>Output:</strong> 0.30000
<strong>Explanation:</strong> The set of balls is [1, 1, 1, 2, 2, 3]. It is hard to display all the 60 possible random shuffles of this set but it is easy to check that 18 of them will have the same number of distinct colors in each box.
Probability = 18 / 60 = 0.3
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> balls = [6,6,6,6,6,6]
<strong>Output:</strong> 0.90327
</pre>



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



<ul><li><code>1 &lt;= balls.length &lt;= 8</code></li><li><code>1 &lt;= balls[i] &lt;= 6</code></li><li><code>sum(balls)</code>&nbsp;is even.</li><li>Answers within&nbsp;<code>10^-5</code>&nbsp;of the actual value will be accepted as correct.</li></ul>



<h2><strong>Solution 0: Permutation</strong> (<strong>TLE</strong>)</h2>



<p>Enumerate all permutations of the balls, count valid ones and divide that by the total.</p>



<p>Time complexity: O((8*6)!) = O(48!) <br>After deduplication: O(48!/(6!)^8) ~ 1.7e38<br>Space complexity: O(8*6)</p>



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

<pre class="crayon-plain-tag">// Author: Huahua, TLE 4/21 passed
class Solution {
public:
  double getProbability(vector&lt;int&gt;&amp; balls) {
    const int k = balls.size();
    vector&lt;int&gt; bs;
    for (int i = 0; i &lt; k; ++i)
      for (int j = 0; j &lt; balls[i]; ++j)
        bs.push_back(i);
    const int n = bs.size();
    double total = 0.0;
    double valid = 0.0;
    // d : depth
    // used : bitmap of bs's usage
    // c1: bitmap of colors of box1
    // c2: bitmap of colors of box1
    function&lt;void(int, long, int, int)&gt; dfs = [&amp;](int d, long used, int c1, int c2) {    
      if (d == n) {          
        total += 1;
        valid += __builtin_popcount(c1) == __builtin_popcount(c2);                
        return;
      }
      for (int i = 0; i &lt; n; ++i) {
        if (used &amp; (1L &lt;&lt; i)) continue;
        // Deduplication.
        if (i &gt; 0 &amp;&amp; bs[i] == bs[i - 1] &amp;&amp; !(used &amp; (1L &lt;&lt; (i - 1)))) continue;        
        int tc1 = (d &lt; n / 2) ? (c1 | (1 &lt;&lt; bs[i])) : c1;
        int tc2 = (d &lt; n / 2) ? c2 : (c2 | (1 &lt;&lt; bs[i]));
        dfs(d + 1, used | (1L &lt;&lt; i), tc1, tc2);
      }
    };
    dfs(0, 0, 0, 0);    
    return valid / total;
  }
};</pre>
</div></div>



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



<p>For each color, put n_i balls into box1, the left t_i &#8211; n_i balls go to box2.<br>permutations = fact(n//2) / PROD(fact(n_i)) * fact(n//2) * PROD(fact(t_i &#8211; n_i))<br>E.g<br>balls = [1&#215;2, 2&#215;6, 3&#215;4]<br>One possible combination:<br>box1: 1 22 333<br>box2: 1 2222 3<br>permutations = 6! / (1! * 2! * 3!) * 6! / (1! * 4! * 1!) = 1800</p>



<p>Time complexity: O((t+1)^k) = O(7^8)<br>Space complexity: O(k + (t*k)) = O(8 + 48)</p>



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

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  double getProbability(vector&lt;int&gt;&amp; balls) {
    const int n = accumulate(begin(balls), end(balls), 0);
    const int k = balls.size();        
    double total = 0.0;
    double valid = 0.0;
    vector&lt;double&gt; fact(50, 1.0);
    for (int i = 1; i &lt; fact.size(); ++i)
      fact[i] = fact[i - 1] * i;
    // d: depth
    // b1, b2: # of balls in box1, box2
    // c1, c2: # of distinct colors in box1, box2
    // p1, p2: # permutations of duplicate balls in box1, box2
    function&lt;void(int, int, int, int, int, double, double)&gt; dfs = [&amp;]
      (int d, int b1, int b2, int c1, int c2, double p1, double p2) {
      if (b1 &gt; n / 2 || b2 &gt; n / 2) return;
      if (d == k) {
        const double count = fact[b1] / p1 * fact[b2] / p2;
        total += count;
        valid += count * (c1 == c2);
        return;
      }
      for (int s1 = 0; s1 &lt;= balls[d]; ++s1) {
        const int s2 = balls[d] - s1;
        dfs(d + 1,
            b1 + s1, 
            b2 + s2,
            c1 + (s1 &gt; 0), 
            c2 + (s2 &gt; 0), 
            p1 * fact[s1], 
            p2 * fact[s2]);
      }
    };
    dfs(0, 0, 0, 0, 0, 1.0, 1.0);
    return valid / total;
  }
};</pre>
</div></div>



<p>vector version</p>



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

<pre class="crayon-plain-tag">// Author: Huahua
class Solution {
public:
  double getProbability(vector&lt;int&gt;&amp; balls) {
    const int k = balls.size();                    
    const int n = accumulate(begin(balls), end(balls), 0);
    vector&lt;double&gt; fact(49, 1.0);
    for (int i = 1; i &lt; fact.size(); ++i)
      fact[i] = fact[i - 1] * i;
    auto perms = [&amp;](const vector&lt;int&gt;&amp; bs, int n) -&gt; double {
      double p = fact[n];
      for (int b : bs) p /= fact[b];        
      return p;
    };
    vector&lt;int&gt; box1, box2;
    function&lt;double(int)&gt; dfs = [&amp;](int d) -&gt; double {
      const int n1 = accumulate(begin(box1), end(box1), 0);
      const int n2 = accumulate(begin(box2), end(box2), 0);
      if (n1 &gt; n / 2 || n2 &gt; n / 2) return 0;
      if (d == k)
        return (box1.size() == box2.size()) * perms(box1, n1) * perms(box2, n2);
      double total = 0;
      for (int s1 = 0; s1 &lt;= balls[d]; ++s1) {
        const int s2 = balls[d] - s1;
        if (s1) box1.push_back(s1);
        if (s2) box2.push_back(s2);
        total += dfs(d + 1);
        if (s1) box1.pop_back();
        if (s2) box2.pop_back();
      }
      return total;
    };
    return dfs(0) / perms(balls, n);
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/searching/leetcode-1467-probability-of-a-two-boxes-having-the-same-number-of-distinct-balls/">花花酱 LeetCode 1467. Probability of a Two Boxes Having The Same Number of Distinct Balls</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-1467-probability-of-a-two-boxes-having-the-same-number-of-distinct-balls/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1411. Number of Ways to Paint N × 3 Grid</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1411-number-of-ways-to-paint-n-x-3-grid/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1411-number-of-ways-to-paint-n-x-3-grid/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 12 Apr 2020 07:08:44 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[combination]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[matrix chain]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=6603</guid>

					<description><![CDATA[<p>You have a&#160;grid&#160;of size&#160;n x 3&#160;and you want to paint each cell of the grid with exactly&#160;one of the three colours:&#160;Red,&#160;Yellow&#160;or&#160;Green&#160;while making sure that no&#8230;</p>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1411-number-of-ways-to-paint-n-x-3-grid/">花花酱 LeetCode 1411. Number of Ways to Paint N × 3 Grid</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 have a&nbsp;<code>grid</code>&nbsp;of size&nbsp;<code>n x 3</code>&nbsp;and you want to paint each cell of the grid with exactly&nbsp;one of the three colours:&nbsp;<strong>Red</strong>,&nbsp;<strong>Yellow</strong>&nbsp;or&nbsp;<strong>Green</strong>&nbsp;while making sure that no two adjacent cells have&nbsp;the same colour (i.e no two cells that share vertical or horizontal sides have the same colour).</p>



<p>You are given&nbsp;<code>n</code>&nbsp;the number of rows of the grid.</p>



<p>Return&nbsp;<em>the number of ways</em>&nbsp;you can paint this&nbsp;<code>grid</code>. As the answer may grow large, the answer&nbsp;<strong>must be</strong>&nbsp;computed modulo&nbsp;<code>10^9 + 7</code>.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 1
<strong>Output:</strong> 12
<strong>Explanation:</strong> There are 12 possible way to paint the grid as shown:

</pre>



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



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



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 3
<strong>Output:</strong> 246
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 7
<strong>Output:</strong> 106494
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 5000
<strong>Output:</strong> 30228214
</pre>



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



<ul><li><code>n == grid.length</code></li><li><code>grid[i].length == 3</code></li><li><code>1 &lt;= n &lt;= 5000</code></li></ul>



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



<p>dp[i][0] := # of ways to paint i rows with 2 different colors at the i-th row<br>dp[i][1] := # of ways to paint i rows with 3 different colors at the i-th row<br>dp[1][0] = dp[1][1] = 6<br>dp[i][0] = dp[i-1][0] * 3 + dp[i-1][1] * 2<br>dp[i][1] = dp[i-1][0] * 2 + dp[i-1][1] * 2</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 numOfWays(int n) {
    constexpr int kMod = 1e9 + 7;
    // dp[i][0] = # of ways to paint i rows with i-th row has 2 colors (e.g. 121)
    // dp[i][1] = # of ways to paint i rows with i-th row has 3 colors (e.g. 123)
    // dp[1][0] = dp[1][1] = 6.
    vector&lt;vector&lt;long&gt;&gt; dp(n + 1, vector&lt;long&gt;(2, 6));        
    for (int i = 2; i &lt;= n; ++i) {
      // 121 =&gt; 2 colors x 3 {212, 232, 313}, 3 colors x 2 {213, 312}
      // 123 =&gt; 2 colors x 2 {212, 232}, 3 colors x 2 {231, 312}      
      dp[i][0] = (dp[i - 1][0] * 3 + dp[i - 1][1] * 2) % kMod;
      dp[i][1] = (dp[i - 1][0] * 2 + dp[i - 1][1] * 2) % kMod;
    }
    return (dp[n][0] + dp[n][1]) % kMod;
  }
};</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 numOfWays(self, n: int) -&amp;gt; int:
    kMod = 10**9 + 7
    dp2, dp3 = 6, 6
    for i in range(1, n):
      t2, t3 = dp2 * 3 + dp3 * 2, dp2 * 2 + dp3 * 2
      dp2, dp3 = t2 % kMod, t3 % kMod
    return (dp2 + dp3) % kMod</pre>
</div></div>



<h2><strong>Solution 2: DP w/ Matrix Chain Multiplication</strong></h2>



<p>ans = {6, 6} * {{3, 2}, {2,2}} ^ (n-1)</p>



<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">// Author: Huahua
class Solution {
public:
  int numOfWays(int n) {
    constexpr long kMod = 1e9 + 7;
    vector&lt;vector&lt;long&gt;&gt; ans{{6, 6}}; // 1x2
    vector&lt;vector&lt;long&gt;&gt; M{{3, 2},{2,2}}; // 2x2
    auto mul = [kMod](const vector&lt;vector&lt;long&gt;&gt;&amp; A, 
                      const vector&lt;vector&lt;long&gt;&gt;&amp; B) {
      const int m = A.size(); // m * n
      const int n = B.size(); // n * p
      const int p = B[0].size();
      vector&lt;vector&lt;long&gt;&gt; C(m, vector&lt;long&gt;(p));
      for (int i = 0; i &lt; m; ++i)
        for (int j = 0; j &lt; p; ++j)
          for (int k = 0; k &lt; n; ++k)
            C[i][j] += (A[i][k] * B[k][j]) % kMod;
      return C;
    };
    --n;
    while (n) {      
      if (n &amp; 1) ans = mul(ans, M); // ans = ans * M;
      M = mul(M, M); // M = M^2
      n &gt;&gt;= 1;
    }
    // ans = ans0 * M^(n-1)
    return (ans[0][0] + ans[0][1]) % kMod;
  }
};</pre>
</div></div>
<p>The post <a rel="nofollow" href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1411-number-of-ways-to-paint-n-x-3-grid/">花花酱 LeetCode 1411. Number of Ways to Paint N × 3 Grid</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/dynamic-programming/leetcode-1411-number-of-ways-to-paint-n-x-3-grid/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
