<?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>search &#8211; Huahua&#8217;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/tag/search/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog</link>
	<description></description>
	<lastBuildDate>Thu, 10 Apr 2025 15:01:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.7.2</generator>

<image>
	<url>https://zxi.mytechroad.com/blog/wp-content/uploads/2017/09/cropped-photo-32x32.jpg</url>
	<title>search &#8211; Huahua&#8217;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>花花酱 LeetCode 650. 2 Keys Keyboard</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-650-2-keys-keyboard/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-650-2-keys-keyboard/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Thu, 10 Apr 2025 14:44:47 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[BFS]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[search]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=10307</guid>

					<description><![CDATA[这道题目还是可以的。每个阶段有两种选择，求最短的决策次数。有好多种不同的做法，我们一个一个来。 方法1: BFS 把问题看成求无权重图中的最短路径，BFS可以找到最优解。 我们的节点有两个状态，当前的长度，剪贴板（上次复制后）的长度。长度超过n一定无解，所以我们的状态最多只有n2种，每个状态最多拓展2个新的节点。 时间复杂度：O(n2)空间复杂度：O(n2) [crayon-67fd0cbdd27a2661517492/]]]></description>
										<content:encoded><![CDATA[
<p>这道题目还是可以的。每个阶段有两种选择，求最短的决策次数。有好多种不同的做法，我们一个一个来。</p>



<p>方法1: BFS<br><br>把问题看成求无权重图中的最短路径，BFS可以找到最优解。</p>



<p>我们的节点有两个状态，当前的长度，剪贴板（上次复制后）的长度。<br>长度超过n一定无解，所以我们的状态最多只有n<sup>2</sup>种，每个状态最多拓展2个新的节点。</p>



<figure class="wp-block-image size-full"><a href="https://zxi.mytechroad.com/blog/wp-content/uploads/2025/04/2-keys.png"><img fetchpriority="high" decoding="async" width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2025/04/2-keys.png" alt="" class="wp-image-10312" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2025/04/2-keys.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2025/04/2-keys-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2025/04/2-keys-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></figure>



<p>时间复杂度：O(n<sup>2</sup>)<br>空间复杂度：O(n<sup>2</sup>)</p>



<pre class="urvanov-syntax-highlighter-plain-tag">class Solution {
public:
  int minSteps(int n) {
    vector&lt;vector&lt;bool&gt;&gt; seen(n + 1, vector&lt;bool&gt;(n + 1));
    queue&lt;pair&lt;int, int&gt;&gt; q;

    auto expand = [&amp;](int len, int clip) {
      if (len &gt; n || len &gt; n || seen[len][clip]) return;
      q.emplace(len, clip);
      seen[len][clip] = true;
    };

    int steps = 0;
    expand(1, 0); // init state.
    while (!q.empty()) {
      int size = q.size();
      while (size--) {
        auto [len, clip] = q.front(); q.pop();
        if (len == n) return steps;
        expand(len, len); // copy.
        expand(len + clip, clip); // paste.
      }
      ++steps;
    }
    return -1;
  }
};</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-650-2-keys-keyboard/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2157. Groups of Strings</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-2157-groups-of-strings/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-2157-groups-of-strings/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 07 Feb 2022 01:03:45 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[connected components]]></category>
		<category><![CDATA[graph]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[union find]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9492</guid>

					<description><![CDATA[You are given a&#160;0-indexed&#160;array of strings&#160;words. Each string consists of&#160;lowercase English letters&#160;only. No letter occurs more than once in any string of&#160;words. Two strings&#160;s1&#160;and&#160;s2&#160;are said&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You are given a&nbsp;<strong>0-indexed</strong>&nbsp;array of strings&nbsp;<code>words</code>. Each string consists of&nbsp;<strong>lowercase English letters</strong>&nbsp;only. No letter occurs more than once in any string of&nbsp;<code>words</code>.</p>



<p>Two strings&nbsp;<code>s1</code>&nbsp;and&nbsp;<code>s2</code>&nbsp;are said to be&nbsp;<strong>connected</strong>&nbsp;if the set of letters of&nbsp;<code>s2</code>&nbsp;can be obtained from the set of letters of&nbsp;<code>s1</code>&nbsp;by any&nbsp;<strong>one</strong>&nbsp;of the following operations:</p>



<ul class="wp-block-list"><li>Adding exactly one letter to the set of the letters of&nbsp;<code>s1</code>.</li><li>Deleting exactly one letter from the set of the letters of&nbsp;<code>s1</code>.</li><li>Replacing exactly one letter from the set of the letters of&nbsp;<code>s1</code>&nbsp;with any letter,&nbsp;<strong>including</strong>&nbsp;itself.</li></ul>



<p>The array&nbsp;<code>words</code>&nbsp;can be divided into one or more non-intersecting&nbsp;<strong>groups</strong>. A string belongs to a group if any&nbsp;<strong>one</strong>&nbsp;of the following is true:</p>



<ul class="wp-block-list"><li>It is connected to&nbsp;<strong>at least one</strong>&nbsp;other string of the group.</li><li>It is the&nbsp;<strong>only</strong>&nbsp;string present in the group.</li></ul>



<p>Note that the strings in&nbsp;<code>words</code>&nbsp;should be grouped in such a manner that a string belonging to a group cannot be connected to a string present in any other group. It can be proved that such an arrangement is always unique.</p>



<p>Return&nbsp;<em>an array</em>&nbsp;<code>ans</code>&nbsp;<em>of size</em>&nbsp;<code>2</code>&nbsp;<em>where:</em></p>



<ul class="wp-block-list"><li><code>ans[0]</code>&nbsp;<em>is the&nbsp;<strong>total number</strong>&nbsp;of groups</em>&nbsp;<code>words</code>&nbsp;<em>can be divided into, and</em></li><li><code>ans[1]</code>&nbsp;<em>is the&nbsp;<strong>size of the largest</strong>&nbsp;group</em>.</li></ul>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> words = ["a","b","ab","cde"]
<strong>Output:</strong> [2,3]
<strong>Explanation:</strong>
- words[0] can be used to obtain words[1] (by replacing 'a' with 'b'), and words[2] (by adding 'b'). So words[0] is connected to words[1] and words[2].
- words[1] can be used to obtain words[0] (by replacing 'b' with 'a'), and words[2] (by adding 'a'). So words[1] is connected to words[0] and words[2].
- words[2] can be used to obtain words[0] (by deleting 'b'), and words[1] (by deleting 'a'). So words[2] is connected to words[0] and words[1].
- words[3] is not connected to any string in words.
Thus, words can be divided into 2 groups ["a","b","ab"] and ["cde"]. The size of the largest group is 3.  
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> words = ["a","ab","abc"]
<strong>Output:</strong> [1,3]
<strong>Explanation:</strong>
- words[0] is connected to words[1].
- words[1] is connected to words[0] and words[2].
- words[2] is connected to words[1].
Since all strings are connected to each other, they should be grouped together.
Thus, the size of the largest group is 3.
</pre>



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



<ul class="wp-block-list"><li><code>1 &lt;= words.length &lt;= 2 * 10<sup>4</sup></code></li><li><code>1 &lt;= words[i].length &lt;= 26</code></li><li><code>words[i]</code>&nbsp;consists of lowercase English letters only.</li><li>No letter occurs more than once in&nbsp;<code>words[i]</code>.</li></ul>



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



<p>Use a bitmask to represent a string. Use dfs to find connected components.</p>



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  vector&lt;int&gt; groupStrings(vector&lt;string&gt;&amp; words) {
    unordered_map&lt;int, int&gt; m;
    for (const string&amp; w : words)
      ++m[accumulate(begin(w), end(w), 0, [](int k, char c){ return k | (1 &lt;&lt; (c - 'a')); })];
    function&lt;int(int)&gt; dfs = [&amp;](int mask) {
      auto it = m.find(mask);
      if (it == end(m)) return 0;
      int ans = it-&gt;second;      
      m.erase(it);
      for (int i = 0; i &lt; 26; ++i) {        
        ans += dfs(mask ^ (1 &lt;&lt; i));
        for (int j = i + 1; j &lt; 26; ++j)
          if ((mask &gt;&gt; i &amp; 1) != (mask &gt;&gt; j &amp; 1))
            ans += dfs(mask ^ (1 &lt;&lt; i) ^ (1 &lt;&lt; j));
      }
      return ans;
    };
    int size = 0;
    int groups = 0;
    while (!m.empty()) {
      size = max(size, dfs(begin(m)-&gt;first));
      ++groups;
    }
    return {groups, size};
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-2157-groups-of-strings/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2081. Sum of k-Mirror Numbers</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-2081-sum-of-k-mirror-numbers/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-2081-sum-of-k-mirror-numbers/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 21 Nov 2021 23:51:32 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[palindrom]]></category>
		<category><![CDATA[search]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8758</guid>

					<description><![CDATA[A&#160;k-mirror number&#160;is a&#160;positive&#160;integer&#160;without leading zeros&#160;that reads the same both forward and backward in base-10&#160;as well as&#160;in base-k. For example,&#160;9&#160;is a 2-mirror number. The representation of&#160;9&#160;in&#8230;]]></description>
										<content:encoded><![CDATA[
<p>A&nbsp;<strong>k-mirror number</strong>&nbsp;is a&nbsp;<strong>positive</strong>&nbsp;integer&nbsp;<strong>without leading zeros</strong>&nbsp;that reads the same both forward and backward in base-10&nbsp;<strong>as well as</strong>&nbsp;in base-k.</p>



<ul class="wp-block-list"><li>For example,&nbsp;<code>9</code>&nbsp;is a 2-mirror number. The representation of&nbsp;<code>9</code>&nbsp;in base-10 and base-2 are&nbsp;<code>9</code>&nbsp;and&nbsp;<code>1001</code>&nbsp;respectively, which read the same both forward and backward.</li><li>On the contrary,&nbsp;<code>4</code>&nbsp;is not a 2-mirror number. The representation of&nbsp;<code>4</code>&nbsp;in base-2 is&nbsp;<code>100</code>, which does not read the same both forward and backward.</li></ul>



<p>Given the base&nbsp;<code>k</code>&nbsp;and the number&nbsp;<code>n</code>, return&nbsp;<em>the&nbsp;<strong>sum</strong>&nbsp;of the</em>&nbsp;<code>n</code>&nbsp;<em><strong>smallest</strong>&nbsp;k-mirror numbers</em>.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> k = 2, n = 5
<strong>Output:</strong> 25
<strong>Explanation:
</strong>The 5 smallest 2-mirror numbers and their representations in base-2 are listed as follows:
  base-10    base-2
    1          1
    3          11
    5          101
    7          111
    9          1001
Their sum = 1 + 3 + 5 + 7 + 9 = 25. 
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> k = 3, n = 7
<strong>Output:</strong> 499
<strong>Explanation:
</strong>The 7 smallest 3-mirror numbers are and their representations in base-3 are listed as follows:
  base-10    base-3
    1          1
    2          2
    4          11
    8          22
    121        11111
    151        12121
    212        21212
Their sum = 1 + 2 + 4 + 8 + 121 + 151 + 212 = 499.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> k = 7, n = 17
<strong>Output:</strong> 20379000
<strong>Explanation:</strong> The 17 smallest 7-mirror numbers are:
1, 2, 3, 4, 5, 6, 8, 121, 171, 242, 292, 16561, 65656, 2137312, 4602064, 6597956, 6958596
</pre>



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



<ul class="wp-block-list"><li><code>2 &lt;= k &lt;= 9</code></li><li><code>1 &lt;= n &lt;= 30</code></li></ul>



<h2 class="wp-block-heading"><strong>Solution: Generate palindromes in base-k.</strong></h2>



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

<pre class="urvanov-syntax-highlighter-plain-tag"># Author: Huahua
class Solution:
  def kMirror(self, k: int, n: int) -&gt; int:
    def getNext(x: str) -&gt; str:
      s = list(x)
      l = len(s)    
      for i in range(l // 2, l):
        if int(s[i]) + 1 &gt;= k: continue
        s[i] = s[~i] = str(int(s[i]) + 1)
        for j in range(l // 2, i): s[j] = s[~j] = &quot;0&quot;
        return &quot;&quot;.join(s)
      return &quot;1&quot; + &quot;0&quot; * (l - 1) + &quot;1&quot;
    ans = 0
    x = &quot;0&quot;
    for _ in range(n):
      while True:
        x = getNext(x)
        val = int(x, k)
        if str(val) == str(val)[::-1]: break
      ans += val
    return ans</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-2081-sum-of-k-mirror-numbers/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2002. Maximum Product of the Length of Two Palindromic Subsequences</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-2002-maximum-product-of-the-length-of-two-palindromic-subsequences/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-2002-maximum-product-of-the-length-of-two-palindromic-subsequences/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 20 Nov 2021 21:50:07 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[search]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8737</guid>

					<description><![CDATA[Given a string&#160;s, find two&#160;disjoint palindromic subsequences&#160;of&#160;s&#160;such that the&#160;product&#160;of their lengths is&#160;maximized. The two subsequences are&#160;disjoint&#160;if they do not both pick a character at the&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Given a string&nbsp;<code>s</code>, find two&nbsp;<strong>disjoint palindromic subsequences</strong>&nbsp;of&nbsp;<code>s</code>&nbsp;such that the&nbsp;<strong>product</strong>&nbsp;of their lengths is&nbsp;<strong>maximized</strong>. The two subsequences are&nbsp;<strong>disjoint</strong>&nbsp;if they do not both pick a character at the same index.</p>



<p>Return&nbsp;<em>the&nbsp;<strong>maximum</strong>&nbsp;possible&nbsp;<strong>product</strong>&nbsp;of the lengths of the two palindromic subsequences</em>.</p>



<p>A&nbsp;<strong>subsequence</strong>&nbsp;is a string that can be derived from another string by deleting some or no characters without changing the order of the remaining characters. A string is&nbsp;<strong>palindromic</strong>&nbsp;if it reads the same forward and backward.</p>



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



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2021/08/24/two-palindromic-subsequences.png" alt="example-1"/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "leetcodecom"
<strong>Output:</strong> 9
<strong>Explanation</strong>: An optimal solution is to choose "ete" for the 1<sup>st</sup> subsequence and "cdc" for the 2<sup>nd</sup> subsequence.
The product of their lengths is: 3 * 3 = 9.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "bb"
<strong>Output:</strong> 1
<strong>Explanation</strong>: An optimal solution is to choose "b" (the first character) for the 1<sup>st</sup> subsequence and "b" (the second character) for the 2<sup>nd</sup> subsequence.
The product of their lengths is: 1 * 1 = 1.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "accbcaxxcxx"
<strong>Output:</strong> 25
<strong>Explanation</strong>: An optimal solution is to choose "accca" for the 1<sup>st</sup> subsequence and "xxcxx" for the 2<sup>nd</sup> subsequence.
The product of their lengths is: 5 * 5 = 25.
</pre>



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



<ul class="wp-block-list"><li><code>2 &lt;= s.length &lt;= 12</code></li><li><code>s</code>&nbsp;consists of lowercase English letters only.</li></ul>



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



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  int maxProduct(string s) {    
    auto isPalindrom = [](const string&amp; s) {
      for (int i = 0; i &lt; s.length(); ++i)
        if (s[i] != s[s.size() - i - 1]) return false;
      return true;
    };
    const int n = s.size();
    vector&lt;string&gt; ss(3);
    size_t ans = 0;
    function&lt;void(int)&gt; dfs = [&amp;](int i) -&gt; void {
      if (i == n) {
        if (isPalindrom(ss[0]) &amp;&amp; isPalindrom(ss[1]))
          ans = max(ans, ss[0].size() * ss[1].size());
        return;
      }
      for (int k = 0; k &lt; 3; ++k) {
        ss[k].push_back(s[i]);
        dfs(i + 1); 
        ss[k].pop_back();  
      }      
    };
    dfs(0);
    return ans;
  }
};</pre>
</div></div>



<h2 class="wp-block-heading"><strong>Solution: Subsets + Bitmask + All Pairs</strong></h2>



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  int maxProduct(string s) {    
    auto isPalindrom = [](const string&amp; s) {
      for (int i = 0; i &lt; s.length(); ++i)
        if (s[i] != s[s.size() - i - 1]) return false;
      return true;
    };
    const int n = s.size();
    unordered_set&lt;int&gt; p;
    for (int i = 0; i &lt; (1 &lt;&lt; n); ++i) {
      string t;
      for (int j = 0; j &lt; n; ++j)
        if (i &gt;&gt; j &amp; 1) t.push_back(s[j]);
      if (isPalindrom(t))
        p.insert(i);
    }
    int ans = 0;
    for (int s1 : p)
      for (int s2 : p) 
        if (!(s1 &amp; s2))
          ans = max(ans, __builtin_popcount(s1) * __builtin_popcount(s2));
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-2002-maximum-product-of-the-length-of-two-palindromic-subsequences/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2065. Maximum Path Quality of a Graph</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-2065-maximum-path-quality-of-a-graph/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-2065-maximum-path-quality-of-a-graph/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 07 Nov 2021 22:09:43 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[search]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8685</guid>

					<description><![CDATA[There is an&#160;undirected&#160;graph with&#160;n&#160;nodes numbered from&#160;0&#160;to&#160;n - 1&#160;(inclusive). You are given a&#160;0-indexed&#160;integer array&#160;values&#160;where&#160;values[i]&#160;is the&#160;value&#160;of the&#160;ith&#160;node. You are also given a&#160;0-indexed&#160;2D integer array&#160;edges, where each&#160;edges[j] =&#8230;]]></description>
										<content:encoded><![CDATA[
<p>There is an&nbsp;<strong>undirected</strong>&nbsp;graph with&nbsp;<code>n</code>&nbsp;nodes numbered from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>n - 1</code>&nbsp;(<strong>inclusive</strong>). You are given a&nbsp;<strong>0-indexed</strong>&nbsp;integer array&nbsp;<code>values</code>&nbsp;where&nbsp;<code>values[i]</code>&nbsp;is the&nbsp;<strong>value&nbsp;</strong>of the&nbsp;<code>i<sup>th</sup></code>&nbsp;node. You are also given a&nbsp;<strong>0-indexed</strong>&nbsp;2D integer array&nbsp;<code>edges</code>, where each&nbsp;<code>edges[j] = [u<sub>j</sub>, v<sub>j</sub>, time<sub>j</sub>]</code>&nbsp;indicates that there is an undirected edge between the nodes&nbsp;<code>u<sub>j</sub></code>&nbsp;and&nbsp;<code>v<sub>j</sub></code>,and it takes&nbsp;<code>time<sub>j</sub></code>&nbsp;seconds to travel between the two nodes. Finally, you are given an integer&nbsp;<code>maxTime</code>.</p>



<p>A&nbsp;<strong>valid</strong>&nbsp;<strong>path</strong>&nbsp;in the graph is any path that starts at node&nbsp;<code>0</code>, ends at node&nbsp;<code>0</code>, and takes&nbsp;<strong>at most</strong>&nbsp;<code>maxTime</code>&nbsp;seconds to complete. You may visit the same node multiple times. The&nbsp;<strong>quality</strong>&nbsp;of a valid path is the&nbsp;<strong>sum</strong>&nbsp;of the values of the&nbsp;<strong>unique nodes</strong>&nbsp;visited in the path (each node&#8217;s value is added&nbsp;<strong>at most once</strong>&nbsp;to the sum).</p>



<p>Return&nbsp;<em>the&nbsp;<strong>maximum</strong>&nbsp;quality of a valid path</em>.</p>



<p><strong>Note:</strong>&nbsp;There are&nbsp;<strong>at most four</strong>&nbsp;edges connected to each node.</p>



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



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2021/10/19/ex1drawio.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> values = [0,32,10,43], edges = [[0,1,10],[1,2,15],[0,3,10]], maxTime = 49
<strong>Output:</strong> 75
<strong>Explanation:</strong>
One possible path is 0 -&gt; 1 -&gt; 0 -&gt; 3 -&gt; 0. The total time taken is 10 + 10 + 10 + 10 = 40 &lt;= 49.
The nodes visited are 0, 1, and 3, giving a maximal path quality of 0 + 32 + 43 = 75.
</pre>



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



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2021/10/19/ex2drawio.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> values = [5,10,15,20], edges = [[0,1,10],[1,2,10],[0,3,10]], maxTime = 30
<strong>Output:</strong> 25
<strong>Explanation:</strong>
One possible path is 0 -&gt; 3 -&gt; 0. The total time taken is 10 + 10 = 20 &lt;= 30.
The nodes visited are 0 and 3, giving a maximal path quality of 5 + 20 = 25.
</pre>



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



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2021/10/19/ex31drawio.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> values = [1,2,3,4], edges = [[0,1,10],[1,2,11],[2,3,12],[1,3,13]], maxTime = 50
<strong>Output:</strong> 7
<strong>Explanation:</strong>
One possible path is 0 -&gt; 1 -&gt; 3 -&gt; 1 -&gt; 0. The total time taken is 10 + 13 + 13 + 10 = 46 &lt;= 50.
The nodes visited are 0, 1, and 3, giving a maximal path quality of 1 + 2 + 4 = 7.</pre>



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



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2021/10/21/ex4drawio.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> values = [0,1,2], edges = [[1,2,10]], maxTime = 10
<strong>Output:</strong> 0
<strong>Explanation:</strong> 
The only path is 0. The total time taken is 0.
The only node visited is 0, giving a maximal path quality of 0.
</pre>



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



<ul class="wp-block-list"><li><code>n == values.length</code></li><li><code>1 &lt;= n &lt;= 1000</code></li><li><code>0 &lt;= values[i] &lt;= 10<sup>8</sup></code></li><li><code>0 &lt;= edges.length &lt;= 2000</code></li><li><code>edges[j].length == 3</code></li><li><code>0 &lt;= u<sub>j&nbsp;</sub>&lt; v<sub>j</sub>&nbsp;&lt;= n - 1</code></li><li><code>10 &lt;= time<sub>j</sub>, maxTime &lt;= 100</code></li><li>All the pairs&nbsp;<code>[u<sub>j</sub>, v<sub>j</sub>]</code>&nbsp;are&nbsp;<strong>unique</strong>.</li><li>There are&nbsp;<strong>at most four</strong>&nbsp;edges connected to each node.</li><li>The graph may not be connected.</li></ul>



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



<p>Given time &gt;= 10 and maxTime &lt;= 100, the path length is at most 10, given at most four edges connected to each node.<br>Time complexity: O(4<sup>10</sup>)<br>Space complexity: O(n)</p>



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  int maximalPathQuality(vector&lt;int&gt;&amp; values, vector&lt;vector&lt;int&gt;&gt;&amp; edges, int maxTime) {
    const int n = values.size();
    vector&lt;vector&lt;pair&lt;int, int&gt;&gt;&gt; g(n);
    for (const auto&amp; e : edges) {
      g[e[0]].emplace_back(e[1], e[2]);
      g[e[1]].emplace_back(e[0], e[2]);
    }
    vector&lt;int&gt; seen(n);
    int ans = 0;
    function&lt;void(int, int, int)&gt; dfs = [&amp;](int u, int t, int s) {
      if (++seen[u] == 1) s += values[u];
      if (u == 0) ans = max(ans, s);
      for (auto [v, d] : g[u])
        if (t + d &lt;= maxTime) dfs(v, t + d, s);
      if (--seen[u] == 0) s -= values[u];
    };
    dfs(0, 0, 0);
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-2065-maximum-path-quality-of-a-graph/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2048. Next Greater Numerically Balanced Number</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-2048-next-greater-numerically-balanced-number/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-2048-next-greater-numerically-balanced-number/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Tue, 26 Oct 2021 03:10:37 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[permutation]]></category>
		<category><![CDATA[search]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8642</guid>

					<description><![CDATA[An integer&#160;x&#160;is&#160;numerically balanced&#160;if for every digit&#160;d&#160;in the number&#160;x, there are&#160;exactly&#160;d&#160;occurrences of that digit in&#160;x. Given an integer&#160;n, return&#160;the&#160;smallest numerically balanced&#160;number&#160;strictly greater&#160;than&#160;n. Example 1: Input: n&#8230;]]></description>
										<content:encoded><![CDATA[
<p>An integer&nbsp;<code>x</code>&nbsp;is&nbsp;<strong>numerically balanced</strong>&nbsp;if for every digit&nbsp;<code>d</code>&nbsp;in the number&nbsp;<code>x</code>, there are&nbsp;<strong>exactly</strong>&nbsp;<code>d</code>&nbsp;occurrences of that digit in&nbsp;<code>x</code>.</p>



<p>Given an integer&nbsp;<code>n</code>, return&nbsp;<em>the&nbsp;<strong>smallest numerically balanced</strong>&nbsp;number&nbsp;<strong>strictly greater</strong>&nbsp;than&nbsp;</em><code>n</code><em>.</em></p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 1
<strong>Output:</strong> 22
<strong>Explanation:</strong> 
22 is numerically balanced since:
- The digit 2 occurs 2 times. 
It is also the smallest numerically balanced number strictly greater than 1.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 1000
<strong>Output:</strong> 1333
<strong>Explanation:</strong> 
1333 is numerically balanced since:
- The digit 1 occurs 1 time.
- The digit 3 occurs 3 times. 
It is also the smallest numerically balanced number strictly greater than 1000.
Note that 1022 cannot be the answer because 0 appeared more than 0 times.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 3000
<strong>Output:</strong> 3133
<strong>Explanation:</strong> 
3133 is numerically balanced since:
- The digit 1 occurs 1 time.
- The digit 3 occurs 3 times.
It is also the smallest numerically balanced number strictly greater than 3000.
</pre>



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



<ul class="wp-block-list"><li><code>0 &lt;= n &lt;= 10<sup>6</sup></code></li></ul>



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



<p>Time complexity: O(log(n)!)<br>Space complexity: O(log(n)) ?</p>



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  int nextBeautifulNumber(int n) {
    const string t = to_string(n);
    vector&lt;int&gt; nums{1,
                     22,
                     122, 333,
                     1333, 4444,
                     14444, 22333, 55555,
                     122333, 155555, 224444, 666666};
    int ans = 1224444;
    for (int num : nums) {
      string s = to_string(num);
      if (s.size() &lt; t.size()) continue;
      else if (s.size() &gt; t.size()) {
        ans = min(ans, num);
      } else { // same length 
        do {
          if (s &gt; t) ans = min(ans, stoi(s));
        } while (next_permutation(begin(s), end(s)));
      }
    }
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-2048-next-greater-numerically-balanced-number/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1849. Splitting a String Into Descending Consecutive Values</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-1849-splitting-a-string-into-descending-consecutive-values/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-1849-splitting-a-string-into-descending-consecutive-values/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 03 May 2021 06:25:54 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[search]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8431</guid>

					<description><![CDATA[You are given a string&#160;s&#160;that consists of only digits. Check if we can split&#160;s&#160;into&#160;two or more non-empty substrings&#160;such that the&#160;numerical values&#160;of the substrings are in&#160;descending&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You are given a string&nbsp;<code>s</code>&nbsp;that consists of only digits.</p>



<p>Check if we can split&nbsp;<code>s</code>&nbsp;into&nbsp;<strong>two or more non-empty substrings</strong>&nbsp;such that the&nbsp;<strong>numerical values</strong>&nbsp;of the substrings are in&nbsp;<strong>descending order</strong>&nbsp;and the&nbsp;<strong>difference</strong>&nbsp;between numerical values of every two&nbsp;<strong>adjacent</strong>&nbsp;<strong>substrings</strong>&nbsp;is equal to&nbsp;<code>1</code>.</p>



<ul class="wp-block-list"><li>For example, the string&nbsp;<code>s = "0090089"</code>&nbsp;can be split into&nbsp;<code>["0090", "089"]</code>&nbsp;with numerical values&nbsp;<code>[90,89]</code>. The values are in descending order and adjacent values differ by&nbsp;<code>1</code>, so this way is valid.</li><li>Another example, the string&nbsp;<code>s = "001"</code>&nbsp;can be split into&nbsp;<code>["0", "01"]</code>,&nbsp;<code>["00", "1"]</code>, or&nbsp;<code>["0", "0", "1"]</code>. However all the ways are invalid because they have numerical values&nbsp;<code>[0,1]</code>,&nbsp;<code>[0,1]</code>, and&nbsp;<code>[0,0,1]</code>&nbsp;respectively, all of which are not in descending order.</li></ul>



<p>Return&nbsp;<code>true</code>&nbsp;<em>if it is possible to split</em>&nbsp;<code>s</code>​​​​​​&nbsp;<em>as described above</em><em>, or&nbsp;</em><code>false</code><em>&nbsp;otherwise.</em></p>



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



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "1234"
<strong>Output:</strong> false
<strong>Explanation:</strong> There is no valid way to split s.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "050043"
<strong>Output:</strong> true
<strong>Explanation:</strong> s can be split into ["05", "004", "3"] with numerical values [5,4,3].
The values are in descending order with adjacent values differing by 1.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "9080701"
<strong>Output:</strong> false
<strong>Explanation:</strong> There is no valid way to split s.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "10009998"
<strong>Output:</strong> true
<strong>Explanation:</strong> s can be split into ["100", "099", "98"] with numerical values [100,99,98].
The values are in descending order with adjacent values differing by 1.
</pre>



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



<ul class="wp-block-list"><li><code>1 &lt;= s.length &lt;= 20</code></li><li><code>s</code>&nbsp;only consists of digits.</li></ul>



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



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">class Solution {
public:
  bool splitString(string s) {
    const int n = s.length();
    vector&lt;long&gt; nums;
    function&lt;bool(int)&gt; dfs = [&amp;](int p) {
      if (p == n) return nums.size() &gt;= 2;
      long cur = 0;
      for (int i = p; i &lt; n &amp;&amp; cur &lt; 1e11; ++i) {        
        cur = cur * 10 + (s[i] - '0');
        if (nums.empty() || cur + 1 == nums.back()) {
          nums.push_back(cur);
          if (dfs(i + 1)) return true;
          nums.pop_back();
        }
        if (!nums.empty() &amp;&amp; cur &gt;= nums.back()) break;                
      }
      return false;
    };
    return dfs(0);
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-1849-splitting-a-string-into-descending-consecutive-values/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1774. Closest Dessert Cost</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1774-closest-dessert-cost/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1774-closest-dessert-cost/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 28 Feb 2021 04:48:52 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[search]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8164</guid>

					<description><![CDATA[You would like to make dessert and are preparing to buy the ingredients. You have&#160;n&#160;ice cream base flavors and&#160;m&#160;types of toppings to choose from. You&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You would like to make dessert and are preparing to buy the ingredients. You have&nbsp;<code>n</code>&nbsp;ice cream base flavors and&nbsp;<code>m</code>&nbsp;types of toppings to choose from. You must follow these rules when making your dessert:</p>



<ul class="wp-block-list"><li>There must be&nbsp;<strong>exactly one</strong>&nbsp;ice cream base.</li><li>You can add&nbsp;<strong>one or more</strong>&nbsp;types of topping or have no toppings at all.</li><li>There are&nbsp;<strong>at most two</strong>&nbsp;of&nbsp;<strong>each type</strong>&nbsp;of topping.</li></ul>



<p>You are given three inputs:</p>



<ul class="wp-block-list"><li><code>baseCosts</code>, an integer array of length&nbsp;<code>n</code>, where each&nbsp;<code>baseCosts[i]</code>&nbsp;represents the price of the&nbsp;<code>i<sup>th</sup></code>&nbsp;ice cream base flavor.</li><li><code>toppingCosts</code>, an integer array of length&nbsp;<code>m</code>, where each&nbsp;<code>toppingCosts[i]</code>&nbsp;is the price of&nbsp;<strong>one</strong>&nbsp;of the&nbsp;<code>i<sup>th</sup></code>&nbsp;topping.</li><li><code>target</code>, an integer representing your target price for dessert.</li></ul>



<p>You want to make a dessert with a total cost as close to&nbsp;<code>target</code>&nbsp;as possible.</p>



<p>Return&nbsp;<em>the closest possible cost of the dessert to&nbsp;</em><code>target</code>. If there are multiple, return&nbsp;<em>the&nbsp;<strong>lower</strong>&nbsp;one.</em></p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> baseCosts = [1,7], toppingCosts = [3,4], target = 10
<strong>Output:</strong> 10
<strong>Explanation:</strong> Consider the following combination (all 0-indexed):
- Choose base 1: cost 7
- Take 1 of topping 0: cost 1 x 3 = 3
- Take 0 of topping 1: cost 0 x 4 = 0
Total: 7 + 3 + 0 = 10.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> baseCosts = [2,3], toppingCosts = [4,5,100], target = 18
<strong>Output:</strong> 17
<strong>Explanation:</strong> Consider the following combination (all 0-indexed):
- Choose base 1: cost 3
- Take 1 of topping 0: cost 1 x 4 = 4
- Take 2 of topping 1: cost 2 x 5 = 10
- Take 0 of topping 2: cost 0 x 100 = 0
Total: 3 + 4 + 10 + 0 = 17. You cannot make a dessert with a total cost of 18.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> baseCosts = [3,10], toppingCosts = [2,5], target = 9
<strong>Output:</strong> 8
<strong>Explanation:</strong> It is possible to make desserts with cost 8 and 10. Return 8 as it is the lower cost.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> baseCosts = [10], toppingCosts = [1], target = 1
<strong>Output:</strong> 10
<strong>Explanation:</strong> Notice that you don't have to have any toppings, but you must have exactly one base.</pre>



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



<ul class="wp-block-list"><li><code>n == baseCosts.length</code></li><li><code>m == toppingCosts.length</code></li><li><code>1 &lt;= n, m &lt;= 10</code></li><li><code>1 &lt;= baseCosts[i], toppingCosts[i] &lt;= 10<sup>4</sup></code></li><li><code>1 &lt;= target &lt;= 10<sup>4</sup></code></li></ul>



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



<p>Pre-compute the costs of all possible combinations of toppings.</p>



<p>Time complexity: O(sum(toppings) * 2 * (m + n)) ~ O(10^6)<br>Space  complexity: O(sum(toppings)) ~ O(10^5)</p>



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  int closestCost(vector&lt;int&gt;&amp; bs, vector&lt;int&gt;&amp; ts, int target) {
    const int kMax = 2 * accumulate(begin(ts), end(ts), 0);
    int min_diff = INT_MAX;
    int ans = INT_MAX;
    vector&lt;int&gt; dp(kMax + 1);
    dp[0] = 1;
    for (int t : ts) {
      for (int i = kMax; i &gt;= 0; --i) {
        if (!dp[i]) continue;
        if (i + t &lt;= kMax) dp[i + t] = 1;
        if (i + 2 * t &lt;= kMax) dp[i + 2 * t] = 1;        
      }
    }   
    for (int i = 0; i &lt;= kMax; ++i) {
      if (!dp[i]) continue;
       for (int b : bs) {
        const int diff = abs(b + i - target);
        if (diff &lt; min_diff || diff == min_diff &amp;&amp; b + i &lt; ans) {
          min_diff = diff;
          ans = b + i;
        }
      }
    }
    return ans;
  }
};</pre>
</div></div>



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



<p>Combination</p>



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  int closestCost(vector&lt;int&gt;&amp; bs, vector&lt;int&gt;&amp; ts, int target) {
    const int m = ts.size();
    int min_diff = INT_MAX;
    int ans = INT_MAX;
    function&lt;void(int, int)&gt; dfs = [&amp;](int s, int cur) {
      if (s == m) {
        for (int b : bs) {
          const int total = b + cur;
          const int diff = abs(total - target);
          if (diff &lt; min_diff 
              || diff == min_diff &amp;&amp; total &lt; ans) {
            min_diff = diff;
            ans = total;
          }
        }
        return;
      }      
      for (int i = s; i &lt; m; ++i) {
        dfs(i + 1, cur);
        dfs(i + 1, cur + ts[i]);
        dfs(i + 1, cur + ts[i] * 2);
      }
    };    
    dfs(0, 0);
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1774-closest-dessert-cost/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1755. Closest Subsequence Sum</title>
		<link>https://zxi.mytechroad.com/blog/algorithms/binary-search/leetcode-1755-closest-subsequence-sum/</link>
					<comments>https://zxi.mytechroad.com/blog/algorithms/binary-search/leetcode-1755-closest-subsequence-sum/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 13 Feb 2021 17:08:29 +0000</pubDate>
				<category><![CDATA[Binary Search]]></category>
		<category><![CDATA[binary search]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[subsets]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8095</guid>

					<description><![CDATA[You are given an integer array nums and an integer goal. You want to choose a subsequence of&#160;nums&#160;such that the sum of its elements is the closest possible&#8230;]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-4-3 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="花花酱 LeetCode 1755. Closest Subsequence Sum - 刷题找工作 EP382" width="500" height="281" src="https://www.youtube.com/embed/CiTqABg6oaw?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<p>You are given an integer array <code>nums</code> and an integer <code>goal</code>.</p>



<p>You want to choose a subsequence of&nbsp;<code>nums</code>&nbsp;such that the sum of its elements is the closest possible to&nbsp;<code>goal</code>. That is, if the sum of the subsequence&#8217;s elements is&nbsp;<code>sum</code>, then you want to&nbsp;<strong>minimize the absolute difference</strong>&nbsp;<code>abs(sum - goal)</code>.</p>



<p>Return&nbsp;<em>the&nbsp;<strong>minimum</strong>&nbsp;possible value of</em>&nbsp;<code>abs(sum - goal)</code>.</p>



<p>Note that a subsequence of an array is an array formed by removing some elements&nbsp;<strong>(possibly all or none)</strong>&nbsp;of the original array.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [5,-7,3,5], goal = 6
<strong>Output:</strong> 0
<strong>Explanation:</strong> Choose the whole array as a subsequence, with a sum of 6.
This is equal to the goal, so the absolute difference is 0.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [7,-9,15,-2], goal = -5
<strong>Output:</strong> 1
<strong>Explanation:</strong> Choose the subsequence [7,-9,-2], with a sum of -4.
The absolute difference is abs(-4 - (-5)) = abs(1) = 1, which is the minimum.
</pre>



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



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



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



<ul class="wp-block-list"><li><code>1 &lt;= nums.length &lt;= 40</code></li><li><code>-10<sup>7</sup>&nbsp;&lt;= nums[i] &lt;= 10<sup>7</sup></code></li><li><code>-10<sup>9</sup>&nbsp;&lt;= goal &lt;= 10<sup>9</sup></code></li></ul>



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



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



<figure class="wp-block-image size-large"><a href="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/02/1755-ep382-2.png"><img loading="lazy" decoding="async" width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/02/1755-ep382-2.png" alt="" class="wp-image-8099" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/02/1755-ep382-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2021/02/1755-ep382-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2021/02/1755-ep382-2-768x432.png 768w" sizes="auto, (max-width: 960px) 100vw, 960px" /></a></figure>



<p>Since n is too large to generate sums for all subsets O(2^n), we have to split the array into half, generate two sum sets. O(2^(n/2)).</p>



<p>Then the problem can be reduced to find the closet sum by picking one number (sum) each from two different arrays which can be solved in O(mlogm), where m = 2^(n/2).</p>



<p>So final time complexity is O(n * 2^(n/2))<br>Space complexity: O(2^(n/2))</p>



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  int minAbsDifference(vector&lt;int&gt;&amp; nums, int goal) {
    const int n = nums.size();
    int ans = abs(goal);
    vector&lt;int&gt; t1{0}, t2{0};
    t1.reserve(1 &lt;&lt; (n / 2 + 1));
    t2.reserve(1 &lt;&lt; (n / 2 + 1));
    for (int i = 0; i &lt; n / 2; ++i)
      for (int j = t1.size() - 1; j &gt;= 0; --j)
        t1.push_back(t1[j] + nums[i]);
    for (int i = n / 2; i &lt; n; ++i)
      for (int j = t2.size() - 1; j &gt;= 0; --j)
        t2.push_back(t2[j] + nums[i]);
    set&lt;int&gt; s2(begin(t2), end(t2));
    for (int x : unordered_set&lt;int&gt;(begin(t1), end(t1))) {
      auto it = s2.lower_bound(goal - x);
      if (it != s2.end())
        ans = min(ans, abs(goal - x - *it));
      if (it != s2.begin())
        ans = min(ans, abs(goal - x - *prev(it)));
    }
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/algorithms/binary-search/leetcode-1755-closest-subsequence-sum/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1718. Construct the Lexicographically Largest Valid Sequence</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-1718-construct-the-lexicographically-largest-valid-sequence/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-1718-construct-the-lexicographically-largest-valid-sequence/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 10 Jan 2021 04:02:45 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[search]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7950</guid>

					<description><![CDATA[Given an integer&#160;n, find a sequence that satisfies all of the following: The integer&#160;1&#160;occurs once in the sequence. Each integer between&#160;2&#160;and&#160;n&#160;occurs twice in the sequence.&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Given an integer&nbsp;<code>n</code>, find a sequence that satisfies all of the following:</p>



<ul class="wp-block-list"><li>The integer&nbsp;<code>1</code>&nbsp;occurs once in the sequence.</li><li>Each integer between&nbsp;<code>2</code>&nbsp;and&nbsp;<code>n</code>&nbsp;occurs twice in the sequence.</li><li>For every integer&nbsp;<code>i</code>&nbsp;between&nbsp;<code>2</code>&nbsp;and&nbsp;<code>n</code>, the&nbsp;<strong>distance</strong>&nbsp;between the two occurrences of&nbsp;<code>i</code>&nbsp;is exactly&nbsp;<code>i</code>.</li></ul>



<p>The&nbsp;<strong>distance</strong>&nbsp;between two numbers on the sequence,&nbsp;<code>a[i]</code>&nbsp;and&nbsp;<code>a[j]</code>, is the absolute difference of their indices,&nbsp;<code>|j - i|</code>.</p>



<p>Return&nbsp;<em>the&nbsp;<strong>lexicographically largest</strong>&nbsp;sequence</em><em>. It is guaranteed that under the given constraints, there is always a solution.</em></p>



<p>A sequence&nbsp;<code>a</code>&nbsp;is lexicographically larger than a sequence&nbsp;<code>b</code>&nbsp;(of the same length) if in the first position where&nbsp;<code>a</code>&nbsp;and&nbsp;<code>b</code>&nbsp;differ, sequence&nbsp;<code>a</code>&nbsp;has a number greater than the corresponding number in&nbsp;<code>b</code>. For example,&nbsp;<code>[0,1,9,0]</code>&nbsp;is lexicographically larger than&nbsp;<code>[0,1,5,6]</code>&nbsp;because the first position they differ is at the third number, and&nbsp;<code>9</code>&nbsp;is greater than&nbsp;<code>5</code>.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> n = 3
<strong>Output:</strong> [3,1,2,3,2]
<strong>Explanation:</strong> [2,3,2,1,3] is also a valid sequence, but [3,1,2,3,2] is the lexicographically largest valid sequence.
</pre>



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



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



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



<ul class="wp-block-list"><li><code>1 &lt;= n &lt;= 20</code></li></ul>



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



<p>Search from left to right, largest to smallest.</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="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
// Author: Huahua
class Solution {
public:
  vector&lt;int&gt; constructDistancedSequence(int n) {
    const int len = 2 * n - 1;
    vector&lt;int&gt; ans(len);    
    function&lt;bool(int, int)&gt; dfs = [&amp;](int i, int s) {      
      if (i == len) return true;
      if (ans[i]) return dfs(i + 1, s);
      for (int d = n; d &gt; 0; --d) {
        const int j = i + (d == 1 ? 0 : d);
        if ((s &amp; (1 &lt;&lt; d)) || j &gt;= len || ans[j]) continue;
        ans[i] = ans[j] = d;
        if (dfs(i + 1, s | (1 &lt;&lt; d))) return true;
        ans[i] = ans[j] = 0;
      }
      return false;
    };
    dfs(0, 0);
    return ans;
  }
};</pre>

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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
  private boolean dfs(int[] ans, int n, int i, int s) {
    if (i == ans.length) return true;
    if (ans[i] &gt; 0) return dfs(ans, n, i + 1, s);
    for (int d = n; d &gt; 0; --d) {
      int j = i + (d == 1 ? 0 : d);
      if ((s &amp; (1 &lt;&lt; d)) &gt; 0 || j &gt;= ans.length || ans[j] &gt; 0)
        continue;
      ans[i] = ans[j] = d;
      if (dfs(ans, n, i + 1, s | (1 &lt;&lt; d))) return true;
      ans[i] = ans[j] = 0;
    }
    return false;
  }
  
  public int[] constructDistancedSequence(int n) {    
    int[] ans = new int[n * 2 - 1];
    dfs(ans, n, 0, 0);
    return ans;
  }  
}</pre>

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

<pre class="urvanov-syntax-highlighter-plain-tag"># Author: Huahua
class Solution:
  def constructDistancedSequence(self, n: int) -&gt; List[int]:
    l = n * 2 - 1
    ans = [0] * l
    def dfs(i, s):
      if i == l: return True
      if ans[i]: return dfs(i + 1, s)
      for d in range(n, 0, -1):
        j = i + (0 if d == 1 else d)
        if s &amp; (1 &lt;&lt; d) or j &gt;= l or ans[j]: continue
        ans[i] = ans[j] = d
        if dfs(i + 1, s | (1 &lt;&lt; d)): return True
        ans[i] = ans[j] = 0
      return False
    dfs(0, 0)
    return ans</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-1718-construct-the-lexicographically-largest-valid-sequence/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1659. Maximize Grid Happiness</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1659-maximize-grid-happiness/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1659-maximize-grid-happiness/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 23 Nov 2020 06:27:48 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[state compression]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7709</guid>

					<description><![CDATA[You are given four integers,&#160;m,&#160;n,&#160;introvertsCount, and&#160;extrovertsCount. You have an&#160;m x n&#160;grid, and there are two types of people: introverts and extroverts. There are&#160;introvertsCount&#160;introverts and&#160;extrovertsCount&#160;extroverts. You&#8230;]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="花花酱 LeetCode 1659. Maximize Grid Happiness - 刷题找工作 EP371" width="500" height="281" src="https://www.youtube.com/embed/QC0A4L-xkYc?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<p>You are given four integers,&nbsp;<code>m</code>,&nbsp;<code>n</code>,&nbsp;<code>introvertsCount</code>, and&nbsp;<code>extrovertsCount</code>. You have an&nbsp;<code>m x n</code>&nbsp;grid, and there are two types of people: introverts and extroverts. There are&nbsp;<code>introvertsCount</code>&nbsp;introverts and&nbsp;<code>extrovertsCount</code>&nbsp;extroverts.</p>



<p>You should decide how many people you want to live in the grid and assign each of them one grid cell. Note that you&nbsp;<strong>do not</strong>&nbsp;have to have all the people living in the grid.</p>



<p>The&nbsp;<strong>happiness</strong>&nbsp;of each person is calculated as follows:</p>



<ul class="wp-block-list"><li>Introverts&nbsp;<strong>start</strong>&nbsp;with&nbsp;<code>120</code>&nbsp;happiness and&nbsp;<strong>lose</strong>&nbsp;<code>30</code>&nbsp;happiness for each neighbor (introvert or extrovert).</li><li>Extroverts&nbsp;<strong>start</strong>&nbsp;with&nbsp;<code>40</code>&nbsp;happiness and&nbsp;<strong>gain</strong>&nbsp;<code>20</code>&nbsp;happiness for each neighbor (introvert or extrovert).</li></ul>



<p>Neighbors live in the directly adjacent cells north, east, south, and west of a person&#8217;s cell.</p>



<p>The&nbsp;<strong>grid happiness</strong>&nbsp;is the&nbsp;<strong>sum</strong>&nbsp;of each person&#8217;s happiness. Return<em>&nbsp;the&nbsp;<strong>maximum possible grid happiness</strong>.</em></p>



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



<figure class="wp-block-image"><img decoding="async" src="https://assets.leetcode.com/uploads/2020/11/05/grid_happiness.png" alt=""/></figure>



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> m = 2, n = 3, introvertsCount = 1, extrovertsCount = 2
<strong>Output:</strong> 240
<strong>Explanation:</strong> Assume the grid is 1-indexed with coordinates (row, column).
We can put the introvert in cell (1,1) and put the extroverts in cells (1,3) and (2,3).
- Introvert at (1,1) happiness: 120 (starting happiness) - (0 * 30) (0 neighbors) = 120
- Extrovert at (1,3) happiness: 40 (starting happiness) + (1 * 20) (1 neighbor) = 60
- Extrovert at (2,3) happiness: 40 (starting happiness) + (1 * 20) (1 neighbor) = 60
The grid happiness is 120 + 60 + 60 = 240.
The above figure shows the grid in this example with each person's happiness. The introvert stays in the light green cell while the extroverts live on the light purple cells.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> m = 3, n = 1, introvertsCount = 2, extrovertsCount = 1
<strong>Output:</strong> 260
<strong>Explanation:</strong> Place the two introverts in (1,1) and (3,1) and the extrovert at (2,1).
- Introvert at (1,1) happiness: 120 (starting happiness) - (1 * 30) (1 neighbor) = 90
- Extrovert at (2,1) happiness: 40 (starting happiness) + (2 * 20) (2 neighbors) = 80
- Introvert at (3,1) happiness: 120 (starting happiness) - (1 * 30) (1 neighbor) = 90
The grid happiness is 90 + 80 + 90 = 260.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> m = 2, n = 2, introvertsCount = 4, extrovertsCount = 0
<strong>Output:</strong> 240
</pre>



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



<ul class="wp-block-list"><li><code>1 &lt;= m, n &lt;= 5</code></li><li><code>0 &lt;= introvertsCount, extrovertsCount &lt;= min(m * n, 6)</code></li></ul>



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



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



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



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



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



<p>dp(x, y, in, ex, mask) := max score at (x, y) with in and ex left and the state of previous row is mask.</p>



<p>Mask is ternary, mask(i) = {0, 1, 2} means {empty, in, ex}, there are at most 3^n = 3^5 = 243 different states.</p>



<p>Total states / Space complexity: O(m*n*3^n*in*ex) = 5*5*3^5*6*6<br>Space complexity: O(m*n*3^n*in*ex)</p>



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

<pre class="urvanov-syntax-highlighter-plain-tag">class Solution {
public:
  int getMaxGridHappiness(int m, int n, int introvertsCount, int extrovertsCount) {
    constexpr int kMaxStates = 243;
    int dp[6][6][7][7][kMaxStates];
    memset(dp, -1, sizeof(dp));
    auto get = [](int val, int i) { return val / static_cast&lt;int&gt;(pow(3, i)) % 3; };
    auto update = [](int val, int s) { return (val * 3 + s) % kMaxStates; };
    vector&lt;int&gt; init{0, 120, 40};
    vector&lt;int&gt; gain{0, -30, 20};
    
    function&lt;int(int,int,int,int,int)&gt; dfs = [&amp;](int x, int y, int in, int ex, int mask) {
      if (in == 0 &amp;&amp; ex == 0) return 0; // Nothing left.
      if (x == n) { x = 0; ++y; }
      if (y == m) return 0; // Done.
      int&amp; ans = dp[x][y][in][ex][mask];      
      if (ans != -1) return ans;
      
      ans = dfs(x + 1, y, in, ex, update(mask, 0)); // Skip current cell.
      
      vector&lt;int&gt; counts{0, in, ex};
      int up = get(mask, n - 1);
      int left = get(mask, 0);         
      for (int i = 1; i &lt;= 2; ++i) {
        if (counts[i] == 0) continue;        
        int s = init[i];
        if (y - 1 &gt;= 0 &amp;&amp; up) s += gain[i] + gain[up];
        if (x - 1 &gt;= 0 &amp;&amp; left) s += gain[i] + gain[left];
        ans = max(ans, s + dfs(x + 1, y, in - (i==1), ex - (i==2), update(mask, i)));
      }
      return ans;
    };
    return dfs(0, 0, introvertsCount, extrovertsCount, 0);
  }
};</pre>

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

<pre class="urvanov-syntax-highlighter-plain-tag"># Author: Huahua
class Solution:
  def getMaxGridHappiness(self, m: int, n: int, I: int, E: int) -&gt; int:    
    init, gain = [None, 120, 40], [None, -30, 20]
    
    get = lambda val, i: (val // (3 ** i)) % 3
    update = lambda val, s: (val * 3 + s) % (3 ** n)
    
    @lru_cache(None)
    def dp(x: int, y: int, i: int, e: int, mask: int) -&gt; int:
      if x == n: x, y = 0, y + 1
      if i + e == 0 or y == m: return 0
      
      ans = dp(x + 1, y, i, e, update(mask, 0))
      up, left = get(mask, n - 1), get(mask, 0)
      
      for cur, count in enumerate([i, e], 1):
        if count == 0: continue
        s = init[cur]
        if x - 1 &gt;= 0 and left: s += gain[cur] + gain[left]
        if y - 1 &gt;= 0 and up: s += gain[cur] + gain[up]
        ans = max(ans, s + dp(x + 1, y, 
                              i - (cur == 1), 
                              e - (cur == 2),
                              update(mask, cur)))
      return ans
    return dp(0, 0, I, E, 0)</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1659-maximize-grid-happiness/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1655. Distribute Repeating Integers</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1655-distribute-repeating-integers/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1655-distribute-repeating-integers/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 14 Nov 2020 20:21:41 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[bitmask]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[search]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7655</guid>

					<description><![CDATA[You are given an array of&#160;n&#160;integers,&#160;nums, where there are at most&#160;50&#160;unique values in the array. You are also given an array of&#160;m&#160;customer order quantities,&#160;quantity, where&#160;quantity[i]&#160;is&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You are given an array of&nbsp;<code>n</code>&nbsp;integers,&nbsp;<code>nums</code>, where there are at most&nbsp;<code>50</code>&nbsp;unique values in the array. You are also given an array of&nbsp;<code>m</code>&nbsp;customer order quantities,&nbsp;<code>quantity</code>, where&nbsp;<code>quantity[i]</code>&nbsp;is the amount of integers the&nbsp;<code>i<sup>th</sup></code>&nbsp;customer ordered. Determine if it is possible to distribute&nbsp;<code>nums</code>&nbsp;such that:</p>



<ul class="wp-block-list"><li>The&nbsp;<code>i<sup>th</sup></code>&nbsp;customer gets&nbsp;<strong>exactly</strong>&nbsp;<code>quantity[i]</code>&nbsp;integers,</li><li>The integers the&nbsp;<code>i<sup>th</sup></code>&nbsp;customer gets are&nbsp;<strong>all equal</strong>, and</li><li>Every customer is satisfied.</li></ul>



<p>Return&nbsp;<code>true</code><em>&nbsp;if it is possible to distribute&nbsp;</em><code>nums</code><em>&nbsp;according to the above conditions</em>.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [1,2,3,4], quantity = [2]
<strong>Output:</strong> false
<strong>Explanation:</strong> The 0th customer cannot be given two different integers.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [1,2,3,3], quantity = [2]
<strong>Output:</strong> true
<strong>Explanation:</strong> The 0th customer is given [3,3]. The integers [1,2] are not used.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [1,1,2,2], quantity = [2,2]
<strong>Output:</strong> true
<strong>Explanation:</strong> The 0th customer is given [1,1], and the 1st customer is given [2,2].
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [1,1,2,3], quantity = [2,2]
<strong>Output:</strong> false
<strong>Explanation:</strong> Although the 0th customer could be given [1,1], the 1st customer cannot be satisfied.</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> nums = [1,1,1,1,1], quantity = [2,3]
<strong>Output:</strong> true
<strong>Explanation:</strong> The 0th customer is given [1,1], and the 1st customer is given [1,1,1].
</pre>



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



<ul class="wp-block-list"><li><code>n == nums.length</code></li><li><code>1 &lt;= n &lt;= 10<sup>5</sup></code></li><li><code>1 &lt;= nums[i] &lt;= 1000</code></li><li><code>m == quantity.length</code></li><li><code>1 &lt;= m &lt;= 10</code></li><li><code>1 &lt;= quantity[i] &lt;= 10<sup>5</sup></code></li><li>There are at most&nbsp;<code>50</code>&nbsp;unique values in&nbsp;<code>nums</code>.</li></ul>



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



<p>Time complexity: O(|vals|^m) <br>Space complexity: O(|vals| + m)</p>



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  bool canDistribute(vector&lt;int&gt;&amp; nums, vector&lt;int&gt;&amp; quantity) {
    unordered_map&lt;int, int&gt; m;
    for (int x : nums) ++m[x];
    vector&lt;int&gt; cnt;
    for (const auto&amp; [x, c] : m) cnt.push_back(c);
    
    const int q = quantity.size();
    const int n = cnt.size();
    function&lt;bool(int)&gt; dfs = [&amp;](int d) {
      if (d == q) return true;
      for (int i = 0; i &lt; n; ++i) 
        if (cnt[i] &gt;= quantity[d]) {
          cnt[i] -= quantity[d];
          if (dfs(d + 1)) return true;
          cnt[i] += quantity[d];
        }
      return false;
    };
    
    sort(rbegin(cnt), rend(cnt));
    sort(rbegin(quantity), rend(quantity));
    
    return dfs(0);
  }
};</pre>
</div></div>



<h2 class="wp-block-heading"><strong>Solution 2: Bitmask + all subsets</strong></h2>



<p>dp(mask, i) := whether we can distribute to a subset of customers represented as a bit mask, using the i-th to (n-1)-th numbers.</p>



<p>Time complexity: O(2^m * m * |vals|) = O(2^10 * 10 * 50)<br>Space complexity: O(2^m * |vals|)</p>



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

<pre class="urvanov-syntax-highlighter-plain-tag">class Solution {
public:
  bool canDistribute(vector&lt;int&gt;&amp; nums, vector&lt;int&gt;&amp; quantity) {
    vector&lt;int&gt; cnt;
    unordered_map&lt;int, int&gt; freq;
    for (int x : nums) ++freq[x]; 
    for (const auto&amp; [x, f] : freq) cnt.push_back(f);
    
    const int n = cnt.size();
    const int m = quantity.size();        
    
    vector&lt;vector&lt;optional&lt;bool&gt;&gt;&gt; cache(1 &lt;&lt; m, vector&lt;optional&lt;bool&gt;&gt;(n));
    
    vector&lt;int&gt; sums(1 &lt;&lt; m);
    for (int mask = 0; mask &lt; 1 &lt;&lt; m; ++mask)
      for (int i = 0; i &lt; m; ++i)
        if (mask &amp; (1 &lt;&lt; i))
          sums[mask] += quantity[i];
    
    function&lt;bool(int, int)&gt; dp = [&amp;](int mask, int i) -&gt; bool {
      if (mask == 0) return true;
      if (i == n) return false;
      
      auto&amp; ans = cache[mask][i];
      
      if (ans.has_value()) return ans.value();
      
      int cur = mask;
      while (cur) {
        if (sums[cur] &lt;= cnt[i] &amp;&amp; dp(mask ^ cur, i + 1)) {
          ans = true;
          return true;
        }
        cur = (cur - 1) &amp; mask;
      }
      
      ans = dp(mask, i + 1);
      return ans.value();
    };
    
    return dp((1 &lt;&lt; m) - 1, 0);
  }
};</pre>

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

<pre class="urvanov-syntax-highlighter-plain-tag"># Author: Huahua
class Solution:
  def canDistribute(self, nums: List[int], 
                    quantity: List[int]) -&gt; bool:    
    cnts = list(Counter(nums).values())
    m = len(quantity)
    n = len(cnts)
    sums = [0] * (1 &lt;&lt; m)
    for mask in range(1 &lt;&lt; m):
      for i in range(m):
        if mask &amp; (1 &lt;&lt; i): sums[mask] += quantity[i]
    
    @lru_cache(None)
    def dp(mask: int, i: int) -&gt; bool:
      if not mask: return True
      if i &lt; 0: return False
      
      cur = mask
      while cur:
        if sums[cur] &lt;= cnts[i] and dp(mask ^ cur, i - 1):
          return True
        cur = (cur - 1) &amp; mask
      
      return dp(mask, i - 1)
    
    return dp((1 &lt;&lt; m) - 1, n - 1)</pre>
</div></div>



<p>Bottom up:</p>



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

<pre class="urvanov-syntax-highlighter-plain-tag">class Solution {
public:
  bool canDistribute(vector&lt;int&gt;&amp; nums, vector&lt;int&gt;&amp; quantity) {
    vector&lt;int&gt; cnt;
    unordered_map&lt;int, int&gt; freq;
    for (int x : nums) ++freq[x]; 
    for (const auto&amp; [x, f] : freq) cnt.push_back(f);
    
    const int n = cnt.size();
    const int m = quantity.size();            
    
    vector&lt;int&gt; sums(1 &lt;&lt; m);
    for (int mask = 0; mask &lt; 1 &lt;&lt; m; ++mask)
      for (int i = 0; i &lt; m; ++i)
        if (mask &amp; (1 &lt;&lt; i))
          sums[mask] += quantity[i];
    
    // dp[mask][i] := use first i types to satisfy mask customers.
    vector&lt;vector&lt;int&gt;&gt; dp(1 &lt;&lt; m, vector&lt;int&gt;(n + 1));
    dp[0][0] = 1;    
    for (int mask = 0; mask &lt; 1 &lt;&lt; m; ++mask)
      for (int i = 0; i &lt; n; ++i) {
        dp[mask][i + 1] |= dp[mask][i];
        for (int cur = mask; cur; cur = (cur - 1) &amp; mask)
          if (sums[cur] &lt;= cnt[i] &amp;&amp; dp[mask ^ cur][i])
            dp[mask][i + 1] = 1;
      }
    
    return dp[(1 &lt;&lt; m) - 1][n];
  }
};</pre>
</div></div>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1655-distribute-repeating-integers/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1654. Minimum Jumps to Reach Home</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-1654-minimum-jumps-to-reach-home/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-1654-minimum-jumps-to-reach-home/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 14 Nov 2020 19:46:45 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[BFS]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[steps]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7652</guid>

					<description><![CDATA[A certain bug&#8217;s home is on the x-axis at position&#160;x. Help them get there from position&#160;0. The bug jumps according to the following rules: It&#8230;]]></description>
										<content:encoded><![CDATA[
<p>A certain bug&#8217;s home is on the x-axis at position&nbsp;<code>x</code>. Help them get there from position&nbsp;<code>0</code>.</p>



<p>The bug jumps according to the following rules:</p>



<ul class="wp-block-list"><li>It can jump exactly&nbsp;<code>a</code>&nbsp;positions&nbsp;<strong>forward</strong>&nbsp;(to the right).</li><li>It can jump exactly&nbsp;<code>b</code>&nbsp;positions&nbsp;<strong>backward</strong>&nbsp;(to the left).</li><li>It cannot jump backward twice in a row.</li><li>It cannot jump to any&nbsp;<code>forbidden</code>&nbsp;positions.</li></ul>



<p>The bug may jump forward&nbsp;<strong>beyond</strong>&nbsp;its home, but it&nbsp;<strong>cannot jump</strong>&nbsp;to positions numbered with&nbsp;<strong>negative</strong>&nbsp;integers.</p>



<p>Given an array of integers&nbsp;<code>forbidden</code>, where&nbsp;<code>forbidden[i]</code>&nbsp;means that the bug cannot jump to the position&nbsp;<code>forbidden[i]</code>, and integers&nbsp;<code>a</code>,&nbsp;<code>b</code>, and&nbsp;<code>x</code>, return&nbsp;<em>the minimum number of jumps needed for the bug to reach its home</em>. If there is no possible sequence of jumps that lands the bug on position&nbsp;<code>x</code>, return&nbsp;<code>-1.</code></p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> forbidden = [14,4,18,1,15], a = 3, b = 15, x = 9
<strong>Output:</strong> 3
<strong>Explanation:</strong> 3 jumps forward (0 -&gt; 3 -&gt; 6 -&gt; 9) will get the bug home.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> forbidden = [8,3,16,6,12,20], a = 15, b = 13, x = 11
<strong>Output:</strong> -1
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> forbidden = [1,6,2,14,5,17,4], a = 16, b = 9, x = 7
<strong>Output:</strong> 2
<strong>Explanation:</strong> One jump forward (0 -&gt; 16) then one jump backward (16 -&gt; 7) will get the bug home.
</pre>



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



<ul class="wp-block-list"><li><code>1 &lt;= forbidden.length &lt;= 1000</code></li><li><code>1 &lt;= a, b, forbidden[i] &lt;= 2000</code></li><li><code>0 &lt;= x &lt;= 2000</code></li><li>All the elements in&nbsp;<code>forbidden</code>&nbsp;are distinct.</li><li>Position&nbsp;<code>x</code>&nbsp;is not forbidden.</li></ul>



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



<p>Normal BFS with two tricks:<br>1. For each position, we need to track whether it&#8217;s reached via a forward jump or backward jump<br>2. How far should we go? If we don&#8217;t limit, it can go forever which leads to TLE/MLE. We can limit the distance to 2*max_jump, e.g. 4000, that&#8217;s maximum distance we can jump back to home in one shot.</p>



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  int minimumJumps(vector&lt;int&gt;&amp; forbidden, int a, int b, int x) {
    constexpr int kMaxPosition = 4000;
    if (x == 0) return 0;
    queue&lt;pair&lt;int, bool&gt;&gt; q{{{0, true}}};
    unordered_set&lt;int&gt; seen1, seen2;
    for (int f : forbidden) seen1.insert(f), seen2.insert(f);
    seen1.insert(0);
    int steps = 0;
    while (!q.empty()) {      
      int size = q.size();
      while (size--) {
        auto [cur, forward] = q.front(); q.pop();        
        if (cur == x) return steps;
        if (cur &gt; kMaxPosition) continue; // no way to go back
        if (seen1.insert(cur + a).second)      
          q.emplace(cur + a, true);
        if (cur - b &gt;= 0 &amp;&amp; forward &amp;&amp; seen2.insert(cur - b).second)
          q.emplace(cur - b, false);
      }
      ++steps;
    }
    return -1;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-1654-minimum-jumps-to-reach-home/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1625. Lexicographically Smallest String After Applying Operations</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-1625-lexicographically-smallest-string-after-applying-operations/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-1625-lexicographically-smallest-string-after-applying-operations/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 18 Oct 2020 18:00:58 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[string]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7528</guid>

					<description><![CDATA[You are given a string&#160;s&#160;of&#160;even length&#160;consisting of digits from&#160;0&#160;to&#160;9, and two integers&#160;a&#160;and&#160;b. You can apply either of the following two operations any number of times&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You are given a string&nbsp;<code>s</code>&nbsp;of&nbsp;<strong>even length</strong>&nbsp;consisting of digits from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>9</code>, and two integers&nbsp;<code>a</code>&nbsp;and&nbsp;<code>b</code>.</p>



<p>You can apply either of the following two operations any number of times and in any order on&nbsp;<code>s</code>:</p>



<ul class="wp-block-list"><li>Add&nbsp;<code>a</code>&nbsp;to all odd indices of&nbsp;<code>s</code>&nbsp;<strong>(0-indexed)</strong>. Digits post&nbsp;<code>9</code>&nbsp;are cycled back to&nbsp;<code>0</code>. For example, if&nbsp;<code>s = "3456"</code>&nbsp;and&nbsp;<code>a = 5</code>,&nbsp;<code>s</code>&nbsp;becomes&nbsp;<code>"3951"</code>.</li><li>Rotate&nbsp;<code>s</code>&nbsp;to the right by&nbsp;<code>b</code>&nbsp;positions. For example, if&nbsp;<code>s = "3456"</code>&nbsp;and&nbsp;<code>b = 1</code>,&nbsp;<code>s</code>&nbsp;becomes&nbsp;<code>"6345"</code>.</li></ul>



<p>Return&nbsp;<em>the&nbsp;<strong>lexicographically smallest</strong>&nbsp;string you can obtain by applying the above operations any number of times on</em>&nbsp;<code>s</code>.</p>



<p>A string&nbsp;<code>a</code>&nbsp;is lexicographically smaller than a string&nbsp;<code>b</code>&nbsp;(of the same length) if in the first position where&nbsp;<code>a</code>&nbsp;and&nbsp;<code>b</code>&nbsp;differ, string&nbsp;<code>a</code>&nbsp;has a letter that appears earlier in the alphabet than the corresponding letter in&nbsp;<code>b</code>. For example,&nbsp;<code>"0158"</code>&nbsp;is lexicographically smaller than&nbsp;<code>"0190"</code>&nbsp;because the first position they differ is at the third letter, and&nbsp;<code>'5'</code>&nbsp;comes before&nbsp;<code>'9'</code>.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "5525", a = 9, b = 2
<strong>Output:</strong> "2050"
<strong>Explanation: </strong>We can apply the following operations:
Start:  "5525"
Rotate: "2555"
Add:    "2454"
Add:    "2353"
Rotate: "5323"
Add:    "5222"
​​​​​​​Add:    "5121"
​​​​​​​Rotate: "2151"
​​​​​​​Add:    "2050"​​​​​​​​​​​​
There is no way to obtain a string that is lexicographically smaller then "2050".
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "74", a = 5, b = 1
<strong>Output:</strong> "24"
<strong>Explanation: </strong>We can apply the following operations:
Start:  "74"
Rotate: "47"
​​​​​​​Add:    "42"
​​​​​​​Rotate: "24"​​​​​​​​​​​​
There is no way to obtain a string that is lexicographically smaller then "24".
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "0011", a = 4, b = 2
<strong>Output:</strong> "0011"
<strong>Explanation: </strong>There are no sequence of operations that will give us a lexicographically smaller string than "0011".
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "43987654", a = 7, b = 3
<strong>Output:</strong> "00553311"
</pre>



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



<ul class="wp-block-list"><li><code>2 &lt;= s.length &lt;= 100</code></li><li><code>s.length</code>&nbsp;is even.</li><li><code>s</code>&nbsp;consists of digits from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>9</code>&nbsp;only.</li><li><code>1 &lt;= a &lt;= 9</code></li><li><code>1 &lt;= b &lt;= s.length - 1</code></li></ul>



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  string findLexSmallestString(string s, int a, int b) {
    unordered_set&lt;string&gt; seen;    
    string ans(s);
    function&lt;void(string)&gt; dfs = [&amp;](const string&amp; s) {
      if (!seen.insert(s).second) return;
      ans = min(ans, s);
      string t(s);
      for (int i = 1; i &lt; s.length(); i += 2)
        t[i] = (t[i] - '0' + a) % 10 + '0';
      dfs(t);
      dfs(s.substr(b) + s.substr(0, b));
    };    
    dfs(s);
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-1625-lexicographically-smallest-string-after-applying-operations/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[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;]]></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 decoding="async" 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 decoding="async" 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 class="wp-block-list"><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 class="wp-block-heading"><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="urvanov-syntax-highlighter-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="urvanov-syntax-highlighter-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>
]]></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>
	</channel>
</rss>
