<?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>string &#8211; Huahua&#8217;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/tag/string/feed/" rel="self" type="application/rss+xml" />
	<link>https://zxi.mytechroad.com/blog</link>
	<description></description>
	<lastBuildDate>Thu, 17 Apr 2025 03:28:51 +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>string &#8211; Huahua&#8217;s Tech Road</title>
	<link>https://zxi.mytechroad.com/blog</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>花花酱 LeetCode 3517. Smallest Palindromic Rearrangement I</title>
		<link>https://zxi.mytechroad.com/blog/string/leetcode-3517-smallest-palindromic-rearrangement-i/</link>
					<comments>https://zxi.mytechroad.com/blog/string/leetcode-3517-smallest-palindromic-rearrangement-i/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Thu, 17 Apr 2025 03:19:33 +0000</pubDate>
				<category><![CDATA[String]]></category>
		<category><![CDATA[Palindrome]]></category>
		<category><![CDATA[sort]]></category>
		<category><![CDATA[string]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=10364</guid>

					<description><![CDATA[这题考查的是排序吧&#8230; 还有rbegin的使用。 普通排序：时间 O(nlogn) / 空间 O(1) 前半部分顺序排序，后半部分逆序排序。 [crayon-68029022e8466497259827/] 计数排序：时间：O(n)，空间：O(n) -> O(1) 首尾一起写 [crayon-68029022e8475841166125/]]]></description>
										<content:encoded><![CDATA[
<p>这题考查的是排序吧&#8230; 还有rbegin的使用。</p>



<p>普通排序：时间 O(nlogn) / 空间 O(1)</p>



<p>前半部分顺序排序，后半部分逆序排序。</p>



<pre class="urvanov-syntax-highlighter-plain-tag">class Solution {
public:
  string smallestPalindrome(string s) {
    const int n = s.length();
    sort(begin(s), begin(s) + n / 2);
    sort(rbegin(s), rbegin(s) + n / 2);
    return s;
  }
};</pre>



<p>计数排序：时间：O(n)，空间：O(n) -> O(1)</p>



<p>首尾一起写</p>



<pre class="urvanov-syntax-highlighter-plain-tag">// 7 ms, 54.65MB
class Solution {
public:
  string smallestPalindrome(string s) {
    vector&lt;int&gt; f(128);
    for (size_t i = 0; i &lt; s.size() / 2; ++i)
      ++f[s[i]];
    auto h=begin(s);
    auto t=rbegin(s);
    for (char c = 'a'; c &lt;= 'z'; ++c)
      while (f[c]--)
        *h++ = *t++ = c;
    return s;
  }
};</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/string/leetcode-3517-smallest-palindromic-rearrangement-i/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2024. Maximize the Confusion of an Exam</title>
		<link>https://zxi.mytechroad.com/blog/sliding-window/leetcode-2024-maximize-the-confusion-of-an-exam/</link>
					<comments>https://zxi.mytechroad.com/blog/sliding-window/leetcode-2024-maximize-the-confusion-of-an-exam/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 12 Apr 2025 17:09:15 +0000</pubDate>
				<category><![CDATA[Sliding Window]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[sliding window]]></category>
		<category><![CDATA[string]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=10343</guid>

					<description><![CDATA[数据规模高达5 *104,我们只能使用O(n)的算法了。 可以想到的就是滑动窗口(sliding window)，由于最长长度未知，我们可以使用动态滑动窗口。 记录当前滑动窗口中T和F出现的次数，如果其中较少的一个&#60;=k，那么就可以全部替换它，使得整个滑动窗口都变成相同的值。如果这个时候滑动窗口长度大于当前最大长度，我们就把滑动窗口变大，右侧+1，并更新最大长度。否则，减少滑动窗口，左侧-1。 时间复杂度：O(n)空间复杂度：O(2) [crayon-68029022e8b38707501298/]]]></description>
										<content:encoded><![CDATA[
<p>数据规模高达5 *10<sup>4</sup>,我们只能使用O(n)的算法了。</p>



<p>可以想到的就是滑动窗口(sliding window)，由于最长长度未知，我们可以使用动态滑动窗口。</p>



<p>记录当前滑动窗口中T和F出现的次数，如果其中较少的一个&lt;=k，那么就可以全部替换它，使得整个滑动窗口都变成相同的值。如果这个时候滑动窗口长度大于当前最大长度，我们就把滑动窗口变大，右侧+1，并更新最大长度。否则，减少滑动窗口，左侧-1。</p>



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



<pre class="urvanov-syntax-highlighter-plain-tag">class Solution {
public:
  int maxConsecutiveAnswers(string_view A, int k) {
    int ans = 0;
    int f = 0;
    array&lt;int, 2&gt; count; // number of 'F' and 'T' in the sliding window
    for (int i = 0; i &lt; A.size(); ++i) {
      ++count[A[i] == 'T'];
      if (min(count[0], count[1]) &lt;= k &amp;&amp; count[0] + count[1] &gt; ans)
        ++ans;
      else
        --count[A[i - ans] == 'T'];
    }
    return ans;
  }
};</pre>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/sliding-window/leetcode-2024-maximize-the-confusion-of-an-exam/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2023. Number of Pairs of Strings With Concatenation Equal to Target</title>
		<link>https://zxi.mytechroad.com/blog/string/leetcode-2023-number-of-pairs-of-strings-with-concatenation-equal-to-target/</link>
					<comments>https://zxi.mytechroad.com/blog/string/leetcode-2023-number-of-pairs-of-strings-with-concatenation-equal-to-target/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Fri, 11 Apr 2025 16:24:45 +0000</pubDate>
				<category><![CDATA[String]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[string]]></category>
		<category><![CDATA[string_view]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=10337</guid>

					<description><![CDATA[方法1: Brute Force 枚举所有的(nums[i], nums[j])组合，相加在和target比较。 时间复杂度：O(mn2) m为字符串的最长长度。空间复杂度：O(m) 优化前 67ms, 49.3M [crayon-68029022e8e0c954988586/] 一些工程上的优化 优化后 3ms, 12.88MB [crayon-68029022e8e13313406902/]]]></description>
										<content:encoded><![CDATA[
<p>方法1: Brute Force</p>



<p>枚举所有的(nums[i], nums[j])组合，相加在和target比较。</p>



<p>时间复杂度：O(mn<sup>2</sup>) m为字符串的最长长度。<br>空间复杂度：O(m)</p>



<p>优化前 67ms, 49.3M</p>



<pre class="urvanov-syntax-highlighter-plain-tag">class Solution {
public:
  int numOfPairs(vector&lt;string&gt;&amp; nums, string target) {
    const int n = nums.size();
    int ans = 0;
    for (int i = 0; i &lt; n; ++i)
      for (int j = 0; j &lt; n; ++j)
        if (i != j &amp;&amp; nums[i] + nums[j] == target)
          ++ans;
    return ans;
  }
};</pre>



<p>一些工程上的优化</p>



<ul class="wp-block-list">
<li>用string_view作为参数类型，减少一次string copy</li>



<li>先比较长度，再判断内容。</li>



<li>string_view.substr 是O(1)时间，和直接用strncmp比较内容是一样的。</li>
</ul>



<p>优化后 3ms, 12.88MB</p>



<pre class="urvanov-syntax-highlighter-plain-tag">class Solution {
public:
  int numOfPairs(vector&lt;string&gt;&amp; nums, string_view target) {
    const int n = nums.size();
    int ans = 0;
    for (int i = 0; i &lt; n; ++i)
      for (int j = 0; j &lt; n; ++j)
        if (i != j 
            &amp;&amp; nums[i].size() + nums[j].size() == target.size()
            &amp;&amp; target.substr(0, nums[i].size()) == nums[i]
            &amp;&amp; target.substr(nums[i].size()) == nums[j])
              ++ans;
    return ans;
  }
};</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/string/leetcode-2023-number-of-pairs-of-strings-with-concatenation-equal-to-target/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2011. Final Value of Variable After Performing Operations</title>
		<link>https://zxi.mytechroad.com/blog/simulation/leetcode-2011-final-value-of-variable-after-performing-operations/</link>
					<comments>https://zxi.mytechroad.com/blog/simulation/leetcode-2011-final-value-of-variable-after-performing-operations/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Fri, 11 Apr 2025 04:04:13 +0000</pubDate>
				<category><![CDATA[Simulation]]></category>
		<category><![CDATA[easy]]></category>
		<category><![CDATA[simulation]]></category>
		<category><![CDATA[string]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=10322</guid>

					<description><![CDATA[C++ 也能写one-liner了。 时间复杂度：O(n)空间复杂度：O(1) [crayon-68029022e9042622902917/]]]></description>
										<content:encoded><![CDATA[
<p>C++ 也能写one-liner了。</p>



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



<pre class="urvanov-syntax-highlighter-plain-tag">class Solution {
public:
  int finalValueAfterOperations(vector&lt;string&gt;&amp; operations) {
    return accumulate(begin(operations), end(operations), 0, [](const auto s, const auto&amp; op){
      return s + (op[1] == '+' ? 1 : -1);
    });
  }
};</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/simulation/leetcode-2011-final-value-of-variable-after-performing-operations/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2296 Design a Text Editor</title>
		<link>https://zxi.mytechroad.com/blog/string/leetcode-2296-design-a-text-editor/</link>
					<comments>https://zxi.mytechroad.com/blog/string/leetcode-2296-design-a-text-editor/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Thu, 03 Apr 2025 04:08:43 +0000</pubDate>
				<category><![CDATA[String]]></category>
		<category><![CDATA[iterator]]></category>
		<category><![CDATA[list]]></category>
		<category><![CDATA[string]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=10252</guid>

					<description><![CDATA[方法1：双向链表来存储文本，迭代器指向光标所在的位置。加一个dummy head会使代码简单很多。 时间复杂度：TextEditor O(1) addText O(&#124;text&#124;) deleteText O(k) cursorLeft O(k) cursorRight(k)空间复杂度：O(n) 由于每个字符需要创建一个节点（17+个字节），虽然没有超时，但实际工程中是不能使用这种方式的。 [crayon-68029022e925a190163148/] 方法2: 用两个string来代表光标左边的字符串和光标右边的字符串。注：右边字符串是反转的。 左右两边的字符串只会增长（或者覆盖），不会缩短，这是用空间换时间。 删除的时候就是修改了长度而已，并没有缩短字符串，所以是O(1)的。如果缩短的话需则要O(k)时间，还要加上内存释放/再分配的时间，应该会慢一些但不多。 移动光标的时候，就是把左边字符串的最后k个copy到右边的最后面，或者反过来。同样没有缩短，只会变长。 时间复杂度: TextEditor O(1) addText O(&#124;text&#124;) deleteText O(1)&#8230;]]></description>
										<content:encoded><![CDATA[
<p>方法1：双向链表来存储文本，迭代器指向光标所在的位置。加一个dummy head会使代码简单很多。</p>



<p>时间复杂度：TextEditor O(1) addText O(|text|) deleteText O(k) cursorLeft O(k) cursorRight(k)<br>空间复杂度：O(n)</p>



<p>由于每个字符需要创建一个节点（17+个字节），虽然没有超时，但实际工程中是不能使用这种方式的。</p>



<pre class="urvanov-syntax-highlighter-plain-tag">// https://zxi.mytechroad.com/blog/string/leetcode-2296-design-a-text-editor/
class TextEditor {
public:
  TextEditor(): data_{'$'}, cursor_{begin(data_)} {}
  
  void addText(string text) {
    for (char c : text)
      cursor_ = data_.insert(++cursor_, c);
  }
  
  int deleteText(int k) {
    for (int i = 0; i &lt; k; ++i) {
      if (cursor_ == begin(data_)) return i;
      data_.erase(cursor_--);
    }
    return k;
  }
  
  string cursorLeft(int k) {
    for (int i = 0; i &lt; k; ++i) {
      if (cursor_ == begin(data_)) break;
      cursor_--;
    }
    return getText();
  }
  
  string cursorRight(int k) {
    for (int i = 0; i &lt; k; ++i) {
      if (cursor_ == prev(end(data_))) break;
      cursor_++;
    }
    return getText();
  }
private:
  string getText() {
    string ans;
    auto it = cursor_;
    for (int i = 0; i &lt; 10; ++i) {
      if (it == begin(data_)) break;
      ans += *it--;
    }
    reverse(begin(ans), end(ans));
    return ans;
  }

  list&lt;char&gt; data_;
  list&lt;char&gt;::iterator cursor_;
};</pre>



<p>方法2: 用两个string来代表光标左边的字符串和光标右边的字符串。注：右边字符串是反转的。</p>



<p>左右两边的字符串只会增长（或者覆盖），不会缩短，这是用空间换时间。</p>



<p>删除的时候就是修改了长度而已，并没有缩短字符串，所以是O(1)的。<br>如果缩短的话需则要O(k)时间，还要加上内存释放/再分配的时间，应该会慢一些但不多。</p>



<p>移动光标的时候，就是把左边字符串的最后k个copy到右边的最后面，或者反过来。同样没有缩短，只会变长。</p>



<p>时间复杂度: TextEditor O(1) addText O(|text|) deleteText O(1) cursorLeft O(k) cursorRight(k)<br>空间复杂度：O(n)，n为构建的最长的字符串</p>



<figure class="wp-block-image size-full"><a href="https://zxi.mytechroad.com/blog/wp-content/uploads/2025/04/Screenshot-2025-04-03-at-9.37.22 PM.png"><img fetchpriority="high" decoding="async" width="676" height="511" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2025/04/Screenshot-2025-04-03-at-9.37.22 PM.png" alt="" class="wp-image-10262" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2025/04/Screenshot-2025-04-03-at-9.37.22 PM.png 676w, https://zxi.mytechroad.com/blog/wp-content/uploads/2025/04/Screenshot-2025-04-03-at-9.37.22 PM-300x227.png 300w" sizes="(max-width: 676px) 100vw, 676px" /></a></figure>



<pre class="urvanov-syntax-highlighter-plain-tag">// https://zxi.mytechroad.com/blog/string/leetcode-2296-design-a-text-editor/
class TextEditor {
public:
  TextEditor() {}
  
  void addText(string_view text) {
    ensureSize(l, m + text.size());
    copy(begin(text), end(text), begin(l) + m);
    m += text.size();
  }
  
  int deleteText(int k) {
    k = min(k, m);
    m -= k;
    return k;
  }
  
  string cursorLeft(int k) {
    ensureSize(r, n + k);
    for (k = min(k, m); k &gt; 0; --k)
      r[n++] = l[--m];
    return getText();
  }
  
  string cursorRight(int k) {
    ensureSize(l, m + k);
    for (k = min(k, n); k &gt; 0; --k)
      l[m++] = r[--n];
    return getText();
  }
private:
  inline void ensureSize(string&amp; s, int size) {
    if (s.size() &lt; size)
      s.resize(size);
  }

  string getText() const {
    return string(begin(l) + m - min(m, 10), begin(l) + m);
  }

  string l;
  string r;
  int m = 0;
  int n = 0;
};</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/string/leetcode-2296-design-a-text-editor/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 3498 Reverse Degree of a String</title>
		<link>https://zxi.mytechroad.com/blog/string/leetcode-3498-reverse-degree-of-a-string/</link>
					<comments>https://zxi.mytechroad.com/blog/string/leetcode-3498-reverse-degree-of-a-string/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 31 Mar 2025 04:15:09 +0000</pubDate>
				<category><![CDATA[String]]></category>
		<category><![CDATA[ascii]]></category>
		<category><![CDATA[simulation]]></category>
		<category><![CDATA[string]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=10247</guid>

					<description><![CDATA[送分题，简单仿真即可。 时间复杂度：O(n)空间复杂度：O(1) [crayon-68029022e94a6878171111/]]]></description>
										<content:encoded><![CDATA[
<p>送分题，简单仿真即可。</p>



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



<pre class="urvanov-syntax-highlighter-plain-tag">// https://zxi.mytechroad.com/blog/string/leetcode-3498-reverse-degree-of-a-string/
class Solution {
public:
  int reverseDegree(string s) {
    int ans = 0;
    for (int i = 0; i &lt; s.size(); ++i)
      ans += ('z' - s[i] + 1) * (i + 1);
    return ans;
  }
};</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/string/leetcode-3498-reverse-degree-of-a-string/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 3029. Minimum Time to Revert Word to Initial State I</title>
		<link>https://zxi.mytechroad.com/blog/string/leetcode-3029-minimum-time-to-revert-word-to-initial-state-i/</link>
					<comments>https://zxi.mytechroad.com/blog/string/leetcode-3029-minimum-time-to-revert-word-to-initial-state-i/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Tue, 06 Feb 2024 02:02:17 +0000</pubDate>
				<category><![CDATA[String]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[prefix]]></category>
		<category><![CDATA[string]]></category>
		<category><![CDATA[surffix]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=10114</guid>

					<description><![CDATA[You are given a&#160;0-indexed&#160;string&#160;word&#160;and an integer&#160;k. At every second, you must perform the following operations: Remove the first&#160;k&#160;characters of&#160;word. Add any&#160;k&#160;characters to the end of&#160;word.&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You are given a&nbsp;<strong>0-indexed</strong>&nbsp;string&nbsp;<code>word</code>&nbsp;and an integer&nbsp;<code>k</code>.</p>



<p>At every second, you must perform the following operations:</p>



<ul class="wp-block-list"><li>Remove the first&nbsp;<code>k</code>&nbsp;characters of&nbsp;<code>word</code>.</li><li>Add any&nbsp;<code>k</code>&nbsp;characters to the end of&nbsp;<code>word</code>.</li></ul>



<p><strong>Note</strong>&nbsp;that you do not necessarily need to add the same characters that you removed. However, you must perform&nbsp;<strong>both</strong>&nbsp;operations at every second.</p>



<p>Return&nbsp;<em>the&nbsp;<strong>minimum</strong>&nbsp;time greater than zero required for</em>&nbsp;<code>word</code>&nbsp;<em>to revert to its&nbsp;<strong>initial</strong>&nbsp;state</em>.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> word = "abacaba", k = 3
<strong>Output:</strong> 2
<strong>Explanation:</strong> At the 1st second, we remove characters "aba" from the prefix of word, and add characters "bac" to the end of word. Thus, word becomes equal to "cababac".
At the 2nd second, we remove characters "cab" from the prefix of word, and add "aba" to the end of word. Thus, word becomes equal to "abacaba" and reverts to its initial state.
It can be shown that 2 seconds is the minimum time greater than zero required for word to revert to its initial state.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> word = "abacaba", k = 4
<strong>Output:</strong> 1
<strong>Explanation:</strong> At the 1st second, we remove characters "abac" from the prefix of word, and add characters "caba" to the end of word. Thus, word becomes equal to "abacaba" and reverts to its initial state.
It can be shown that 1 second is the minimum time greater than zero required for word to revert to its initial state.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> word = "abcbabcd", k = 2
<strong>Output:</strong> 4
<strong>Explanation:</strong> At every second, we will remove the first 2 characters of word, and add the same characters to the end of word.
After 4 seconds, word becomes equal to "abcbabcd" and reverts to its initial state.
It can be shown that 4 seconds is the minimum time greater than zero required for word to revert to its initial state.
</pre>



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



<ul class="wp-block-list"><li><code>1 &lt;= word.length &lt;= 50</code></li><li><code>1 &lt;= k &lt;= word.length</code></li><li><code>word</code>&nbsp;consists only of lowercase English letters.</li></ul>



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



<p>Compare the suffix with prefix.</p>



<p>word = &#8220;abacaba&#8221;, k = 3<br>ans = 1, &#8220;<s>aba</s>caba&#8221; != &#8220;abac<s>aba</s>&#8220;<br>ans = 2, &#8220;<s>abacab</s>a&#8221; == &#8220;a<s>bacaba</s>&#8220;, we find it.</p>



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">class Solution {
public:
  int minimumTimeToInitialState(string_view word, int k) {
    const int n = word.length();
    for (int i = 1; i * k &lt; n; ++i) {
      string_view t = word.substr(i * k);
      if (t == word.substr(0, t.length())) return i;
    }      
    return (n + k - 1) / k;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/string/leetcode-3029-minimum-time-to-revert-word-to-initial-state-i/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2828. Check if a String Is an Acronym of Words</title>
		<link>https://zxi.mytechroad.com/blog/string/leetcode-2828-check-if-a-string-is-an-acronym-of-words/</link>
					<comments>https://zxi.mytechroad.com/blog/string/leetcode-2828-check-if-a-string-is-an-acronym-of-words/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 26 Aug 2023 16:29:43 +0000</pubDate>
				<category><![CDATA[String]]></category>
		<category><![CDATA[easy]]></category>
		<category><![CDATA[string]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=10082</guid>

					<description><![CDATA[Given an array of strings&#160;words&#160;and a string&#160;s, determine if&#160;s&#160;is an&#160;acronym&#160;of words. The string&#160;s&#160;is considered an acronym of&#160;words&#160;if it can be formed by concatenating the&#160;first&#160;character of&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Given an array of strings&nbsp;<code>words</code>&nbsp;and a string&nbsp;<code>s</code>, determine if&nbsp;<code>s</code>&nbsp;is an&nbsp;<strong>acronym</strong>&nbsp;of words.</p>



<p>The string&nbsp;<code>s</code>&nbsp;is considered an acronym of&nbsp;<code>words</code>&nbsp;if it can be formed by concatenating the&nbsp;<strong>first</strong>&nbsp;character of each string in&nbsp;<code>words</code>&nbsp;<strong>in order</strong>. For example,&nbsp;<code>"ab"</code>&nbsp;can be formed from&nbsp;<code>["apple", "banana"]</code>, but it can&#8217;t be formed from&nbsp;<code>["bear", "aardvark"]</code>.</p>



<p>Return&nbsp;<code>true</code><em>&nbsp;if&nbsp;</em><code>s</code><em>&nbsp;is an acronym of&nbsp;</em><code>words</code><em>, and&nbsp;</em><code>false</code><em>&nbsp;otherwise.</em></p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> words = ["alice","bob","charlie"], s = "abc"
<strong>Output:</strong> true
<strong>Explanation:</strong> The first character in the words "alice", "bob", and "charlie" are 'a', 'b', and 'c', respectively. Hence, s = "abc" is the acronym. 
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> words = ["an","apple"], s = "a"
<strong>Output:</strong> false
<strong>Explanation:</strong> The first character in the words "an" and "apple" are 'a' and 'a', respectively. 
The acronym formed by concatenating these characters is "aa". 
Hence, s = "a" is not the acronym.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> words = ["never","gonna","give","up","on","you"], s = "ngguoy"
<strong>Output:</strong> true
<strong>Explanation: </strong>By concatenating the first character of the words in the array, we get the string "ngguoy". 
Hence, s = "ngguoy" is the acronym.
</pre>



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



<ul class="wp-block-list"><li><code>1 &lt;= words.length &lt;= 100</code></li><li><code>1 &lt;= words[i].length &lt;= 10</code></li><li><code>1 &lt;= s.length &lt;= 100</code></li><li><code>words[i]</code>&nbsp;and&nbsp;<code>s</code>&nbsp;consist of lowercase English letters.<br></li></ul>



<h2 class="wp-block-heading"><strong>Solution: Check the first letter of each word</strong></h2>



<p>No need to concatenate, just check the first letter of each word.</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="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  bool isAcronym(vector&lt;string&gt;&amp; words, string_view s) {
    if (words.size() != s.size()) return false;
    for (int i = 0; i &lt; s.size(); ++i)
      if (words[i][0] != s[i]) return false;
    return true;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/string/leetcode-2828-check-if-a-string-is-an-acronym-of-words/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2825. Make String a Subsequence Using Cyclic Increments</title>
		<link>https://zxi.mytechroad.com/blog/two-pointers/leetcode-2825-make-string-a-subsequence-using-cyclic-increments/</link>
					<comments>https://zxi.mytechroad.com/blog/two-pointers/leetcode-2825-make-string-a-subsequence-using-cyclic-increments/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Thu, 24 Aug 2023 04:38:17 +0000</pubDate>
				<category><![CDATA[Two pointers]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[string]]></category>
		<category><![CDATA[subsequence]]></category>
		<category><![CDATA[two pointers]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=10077</guid>

					<description><![CDATA[You are given two&#160;0-indexed&#160;strings&#160;str1&#160;and&#160;str2. In an operation, you select a&#160;set&#160;of indices in&#160;str1, and for each index&#160;i&#160;in the set, increment&#160;str1[i]&#160;to the next character&#160;cyclically. That is&#160;'a'&#160;becomes&#160;'b',&#160;'b'&#160;becomes&#160;'c', and&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You are given two&nbsp;<strong>0-indexed</strong>&nbsp;strings&nbsp;<code>str1</code>&nbsp;and&nbsp;<code>str2</code>.</p>



<p>In an operation, you select a&nbsp;<strong>set</strong>&nbsp;of indices in&nbsp;<code>str1</code>, and for each index&nbsp;<code>i</code>&nbsp;in the set, increment&nbsp;<code>str1[i]</code>&nbsp;to the next character&nbsp;<strong>cyclically</strong>. That is&nbsp;<code>'a'</code>&nbsp;becomes&nbsp;<code>'b'</code>,&nbsp;<code>'b'</code>&nbsp;becomes&nbsp;<code>'c'</code>, and so on, and&nbsp;<code>'z'</code>&nbsp;becomes&nbsp;<code>'a'</code>.</p>



<p>Return&nbsp;<code>true</code>&nbsp;<em>if it is possible to make&nbsp;</em><code>str2</code>&nbsp;<em>a subsequence of&nbsp;</em><code>str1</code>&nbsp;<em>by performing the operation&nbsp;<strong>at most once</strong></em>,&nbsp;<em>and</em>&nbsp;<code>false</code>&nbsp;<em>otherwise</em>.</p>



<p><strong>Note:</strong>&nbsp;A subsequence of a string is a new string that is formed from the original string by deleting some (possibly none) of the characters without disturbing the relative positions of the remaining characters.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> str1 = "abc", str2 = "ad"
<strong>Output:</strong> true
<strong>Explanation:</strong> Select index 2 in str1.
Increment str1[2] to become 'd'. 
Hence, str1 becomes "abd" and str2 is now a subsequence. Therefore, true is returned.</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> str1 = "zc", str2 = "ad"
<strong>Output:</strong> true
<strong>Explanation:</strong> Select indices 0 and 1 in str1. 
Increment str1[0] to become 'a'. 
Increment str1[1] to become 'd'. 
Hence, str1 becomes "ad" and str2 is now a subsequence. Therefore, true is returned.</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> str1 = "ab", str2 = "d"
<strong>Output:</strong> false
<strong>Explanation:</strong> In this example, it can be shown that it is impossible to make str2 a subsequence of str1 using the operation at most once. 
Therefore, false is returned.</pre>



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



<ul class="wp-block-list"><li><code>1 &lt;= str1.length &lt;= 10<sup>5</sup></code></li><li><code>1 &lt;= str2.length &lt;= 10<sup>5</sup></code></li><li><code>str1</code>&nbsp;and&nbsp;<code>str2</code>&nbsp;consist of only lowercase English letters.</li></ul>



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



<p>s1[i] and s2[j] can match if <br>s1[i] == s2[j] or inc(s1[i]) == s2[j]</p>



<p>If matched: ++i; ++j else ++i.</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="urvanov-syntax-highlighter-plain-tag">class Solution {
public:
  bool canMakeSubsequence(string_view s1, string_view s2) {    
    for (int i = 0, j = 0, n = s1.size(), m = s2.size(); i &lt; n; ++i)
      if (s1[i] == s2[j] || (s1[i] - 'a' + 1) % 26 == s2[j] - 'a')
        if (++j == m) return true;
    return false;
  }
};</pre>
</div></div>



<p>Iterator version</p>



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

<pre class="urvanov-syntax-highlighter-plain-tag">class Solution {
public:
  bool canMakeSubsequence(string_view s1, string_view s2) {    
    for (auto i = begin(s1), j = begin(s2); i != end(s1); ++i)
      if (*i == *j || (*i - 'a' + 1) % 26 == *j - 'a')
        if (++j == end(s2)) return true;
    return false;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/two-pointers/leetcode-2825-make-string-a-subsequence-using-cyclic-increments/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2586. Count the Number of Vowel Strings in Range</title>
		<link>https://zxi.mytechroad.com/blog/string/leetcode-2586-count-the-number-of-vowel-strings-in-range/</link>
					<comments>https://zxi.mytechroad.com/blog/string/leetcode-2586-count-the-number-of-vowel-strings-in-range/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 12 Mar 2023 04:32:34 +0000</pubDate>
				<category><![CDATA[String]]></category>
		<category><![CDATA[easy]]></category>
		<category><![CDATA[string]]></category>
		<category><![CDATA[vowel]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9977</guid>

					<description><![CDATA[You are given a&#160;0-indexed&#160;array of string&#160;words&#160;and two integers&#160;left&#160;and&#160;right. A string is called a&#160;vowel string&#160;if it starts with a vowel character and ends with a vowel&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You are given a&nbsp;<strong>0-indexed</strong>&nbsp;array of string&nbsp;<code>words</code>&nbsp;and two integers&nbsp;<code>left</code>&nbsp;and&nbsp;<code>right</code>.</p>



<p>A string is called a&nbsp;<strong>vowel string</strong>&nbsp;if it starts with a vowel character and ends with a vowel character where vowel characters are&nbsp;<code>'a'</code>,&nbsp;<code>'e'</code>,&nbsp;<code>'i'</code>,&nbsp;<code>'o'</code>, and&nbsp;<code>'u'</code>.</p>



<p>Return&nbsp;<em>the number of vowel strings&nbsp;</em><code>words[i]</code><em>&nbsp;where&nbsp;</em><code>i</code><em>&nbsp;belongs to the inclusive range&nbsp;</em><code>[left, right]</code>.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> words = ["are","amy","u"], left = 0, right = 2
<strong>Output:</strong> 2
<strong>Explanation:</strong> 
- "are" is a vowel string because it starts with 'a' and ends with 'e'.
- "amy" is not a vowel string because it does not end with a vowel.
- "u" is a vowel string because it starts with 'u' and ends with 'u'.
The number of vowel strings in the mentioned range is 2.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> words = ["hey","aeo","mu","ooo","artro"], left = 1, right = 4
<strong>Output:</strong> 3
<strong>Explanation:</strong> 
- "aeo" is a vowel string because it starts with 'a' and ends with 'o'.
- "mu" is not a vowel string because it does not start with a vowel.
- "ooo" is a vowel string because it starts with 'o' and ends with 'o'.
- "artro" is a vowel string because it starts with 'a' and ends with 'o'.
The number of vowel strings in the mentioned range is 3.
</pre>



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



<ul class="wp-block-list"><li><code>1 &lt;= words.length &lt;= 1000</code></li><li><code>1 &lt;= words[i].length &lt;= 10</code></li><li><code>words[i]</code>&nbsp;consists of only lowercase English letters.</li><li><code>0 &lt;= left &lt;= right &lt; words.length</code></li></ul>



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



<p>Iterator overs words, from left to right. Check the first and last element of the string.</p>



<p>Time complexity: O(|right &#8211; left + 1|)<br>Space complexity: O(1)</p>



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  int vowelStrings(vector&lt;string&gt;&amp; words, int left, int right) {
    auto isVowel = [](char c) {
      return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u';
    };
    return count_if(begin(words) + left, begin(words) + right + 1, [&amp;](const string&amp; w) {
      return isVowel(w.front()) &amp;&amp; isVowel(w.back());
    });
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/string/leetcode-2586-count-the-number-of-vowel-strings-in-range/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2564. Substring XOR Queries</title>
		<link>https://zxi.mytechroad.com/blog/hashtable/leetcode-2564-substring-xor-queries/</link>
					<comments>https://zxi.mytechroad.com/blog/hashtable/leetcode-2564-substring-xor-queries/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 12 Feb 2023 16:50:41 +0000</pubDate>
				<category><![CDATA[Hashtable]]></category>
		<category><![CDATA[hashtable]]></category>
		<category><![CDATA[precompute]]></category>
		<category><![CDATA[string]]></category>
		<category><![CDATA[xor]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9942</guid>

					<description><![CDATA[You are given a&#160;binary string&#160;s, and a&#160;2D&#160;integer array&#160;queries&#160;where&#160;queries[i] = [firsti, secondi]. For the&#160;ith&#160;query, find the&#160;shortest substring&#160;of&#160;s&#160;whose&#160;decimal value,&#160;val, yields&#160;secondi&#160;when&#160;bitwise XORed&#160;with&#160;firsti. In other words,&#160;val ^ firsti ==&#8230;]]></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 2564. Substring XOR Queries - 刷题找工作 EP410" width="500" height="281" src="https://www.youtube.com/embed/UsH8x4Fg4DI?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 a&nbsp;<strong>binary string</strong>&nbsp;<code>s</code>, and a&nbsp;<strong>2D</strong>&nbsp;integer array&nbsp;<code>queries</code>&nbsp;where&nbsp;<code>queries[i] = [first<sub>i</sub>, second<sub>i</sub>]</code>.</p>



<p>For the&nbsp;<code>i<sup>th</sup></code>&nbsp;query, find the&nbsp;<strong>shortest substring</strong>&nbsp;of&nbsp;<code>s</code>&nbsp;whose&nbsp;<strong>decimal value</strong>,&nbsp;<code>val</code>, yields&nbsp;<code>second<sub>i</sub></code>&nbsp;when&nbsp;<strong>bitwise XORed</strong>&nbsp;with&nbsp;<code>first<sub>i</sub></code>. In other words,&nbsp;<code>val ^ first<sub>i</sub> == second<sub>i</sub></code>.</p>



<p>The answer to the&nbsp;<code>i<sup>th</sup></code>&nbsp;query is the endpoints (<strong>0-indexed</strong>) of the substring&nbsp;<code>[left<sub>i</sub>, right<sub>i</sub>]</code>&nbsp;or&nbsp;<code>[-1, -1]</code>&nbsp;if no such substring exists. If there are multiple answers, choose the one with the&nbsp;<strong>minimum</strong>&nbsp;<code>left<sub>i</sub></code>.</p>



<p><em>Return an array</em>&nbsp;<code>ans</code>&nbsp;<em>where</em>&nbsp;<code>ans[i] = [left<sub>i</sub>, right<sub>i</sub>]</code>&nbsp;<em>is the answer to the</em>&nbsp;<code>i<sup>th</sup></code>&nbsp;<em>query.</em></p>



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



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "101101", queries = [[0,5],[1,2]]
<strong>Output:</strong> [[0,2],[2,3]]
<strong>Explanation:</strong> For the first query the substring in range <code>[0,2]</code> is <strong>"101"</strong> which has a decimal value of <strong><code>5</code></strong>, and <strong><code>5 ^ 0 = 5</code></strong>, hence the answer to the first query is <code>[0,2]</code>. In the second query, the substring in range <code>[2,3]</code> is <strong>"11",</strong> and has a decimal value of <strong>3</strong>, and <strong>3<code> ^ 1 = 2</code></strong>.&nbsp;So, <code>[2,3]</code> is returned for the second query. 
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "0101", queries = [[12,8]]
<strong>Output:</strong> [[-1,-1]]
<strong>Explanation:</strong> In this example there is no substring that answers the query, hence <code>[-1,-1] is returned</code>.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "1", queries = [[4,5]]
<strong>Output:</strong> [[0,0]]
<strong>Explanation:</strong> For this example, the substring in range <code>[0,0]</code> has a decimal value of <strong><code>1</code></strong>, and <strong><code>1 ^ 4 = 5</code></strong>. So, the answer is <code>[0,0]</code>.
</pre>



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



<ul class="wp-block-list"><li><code>1 &lt;= s.length &lt;= 10<sup>4</sup></code></li><li><code>s[i]</code>&nbsp;is either&nbsp;<code>'0'</code>&nbsp;or&nbsp;<code>'1'</code>.</li><li><code>1 &lt;= queries.length &lt;= 10<sup>5</sup></code></li><li><code>0 &lt;= first<sub>i</sub>, second<sub>i</sub> &lt;= 10<sup>9</sup></code></li></ul>



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



<p>We can pre-compute all possible substrings</p>



<p>Time complexity: O(n*32 + m)<br>Space complexity: O(n*32)</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;vector&lt;int&gt;&gt; substringXorQueries(string s, vector&lt;vector&lt;int&gt;&gt;&amp; queries) {
    unordered_map&lt;int, vector&lt;int&gt;&gt; m;
    const int l = s.length();
    for (int i = 0; i &lt; l; ++i) {
      if (s[i] == '0') {
        if (!m.count(0)) m[0] = {i, i};
        continue;
      }
      for (int j = 0, cur = 0; j &lt; 32 &amp;&amp; i + j &lt; l; ++j) {
        cur = (cur &lt;&lt; 1) | (s[i + j] - '0');
        if (!m.count(cur))
          m[cur] = {i, i + j};
      }
    }
    vector&lt;vector&lt;int&gt;&gt; ans;    
    for (const auto&amp; q : queries) {
      int x = q[0] ^ q[1];
      if (m.count(x)) 
        ans.push_back(m[x]);
      else
        ans.push_back({-1, -1});
    }
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/hashtable/leetcode-2564-substring-xor-queries/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2559. Count Vowel Strings in Ranges</title>
		<link>https://zxi.mytechroad.com/blog/algorithms/array/leetcode-2559-count-vowel-strings-in-ranges/</link>
					<comments>https://zxi.mytechroad.com/blog/algorithms/array/leetcode-2559-count-vowel-strings-in-ranges/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 05 Feb 2023 05:25:04 +0000</pubDate>
				<category><![CDATA[Array]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[prefix sum]]></category>
		<category><![CDATA[string]]></category>
		<category><![CDATA[vowel]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9929</guid>

					<description><![CDATA[You are given a&#160;0-indexed&#160;array of strings&#160;words&#160;and a 2D array of integers&#160;queries. Each query&#160;queries[i] = [li, ri]&#160;asks us to find the number of strings present in&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You are given a&nbsp;<strong>0-indexed</strong>&nbsp;array of strings&nbsp;<code>words</code>&nbsp;and a 2D array of integers&nbsp;<code>queries</code>.</p>



<p>Each query&nbsp;<code>queries[i] = [l<sub>i</sub>, r<sub>i</sub>]</code>&nbsp;asks us to find the number of strings present in the range&nbsp;<code>l<sub>i</sub></code>&nbsp;to&nbsp;<code>r<sub>i</sub></code>&nbsp;(both&nbsp;<strong>inclusive</strong>) of&nbsp;<code>words</code>&nbsp;that start and end with a vowel.</p>



<p>Return an array&nbsp;<code>ans</code>&nbsp;of size&nbsp;<code>queries.length</code>, where&nbsp;<code>ans[i]</code>&nbsp;is the answer to the&nbsp;<code>i</code><sup>th</sup>&nbsp;query.</p>



<p><strong>Note</strong>&nbsp;that the vowel letters are&nbsp;<code>'a'</code>,&nbsp;<code>'e'</code>,&nbsp;<code>'i'</code>,&nbsp;<code>'o'</code>, and&nbsp;<code>'u'</code>.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> words = ["aba","bcb","ece","aa","e"], queries = [[0,2],[1,4],[1,1]]
<strong>Output:</strong> [2,3,0]
<strong>Explanation:</strong> The strings starting and ending with a vowel are "aba", "ece", "aa" and "e".
The answer to the query [0,2] is 2 (strings "aba" and "ece").
to query [1,4] is 3 (strings "ece", "aa", "e").
to query [1,1] is 0.
We return [2,3,0].
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> words = ["a","e","i"], queries = [[0,2],[0,1],[2,2]]
<strong>Output:</strong> [3,2,1]
<strong>Explanation:</strong> Every string satisfies the conditions, so we return [3,2,1].</pre>



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



<ul class="wp-block-list"><li><code>1 &lt;= words.length &lt;= 10<sup>5</sup></code></li><li><code>1 &lt;= words[i].length &lt;= 40</code></li><li><code>words[i]</code>&nbsp;consists only of lowercase English letters.</li><li><code>sum(words[i].length) &lt;= 3 * 10<sup>5</sup></code></li><li><code>1 &lt;= queries.length &lt;= 10<sup>5</sup></code></li><li><code>0 &lt;= l<sub>i</sub> &lt;= r<sub>i</sub> &lt;&nbsp;words.length</code></li></ul>



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



<p>Let sum[i] := number of valid strings in words[0:i]</p>



<p>For each query [l, r], answer will be sum[r + 1] &#8211; sum[l]</p>



<p>Time complexity: O(n + q)<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; vowelStrings(vector&lt;string&gt;&amp; words, vector&lt;vector&lt;int&gt;&gt;&amp; queries) {
    const size_t n = words.size();
    vector&lt;int&gt; sum(n + 1);
    auto check = [](char c) {
      return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u';
    };
    for (size_t i = 0; i &lt; n; ++i)
      sum[i + 1] = sum[i] + 
        (check(words[i][0]) &amp;&amp; check(words[i][words[i].size() - 1]));
    vector&lt;int&gt; ans;
    for (const auto&amp; q : queries)
      ans.push_back(sum[q[1] + 1] - sum[q[0]]);
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/algorithms/array/leetcode-2559-count-vowel-strings-in-ranges/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2452. Words Within Two Edits of Dictionary</title>
		<link>https://zxi.mytechroad.com/blog/string/leetcode-2452-words-within-two-edits-of-dictionary%ef%bf%bc/</link>
					<comments>https://zxi.mytechroad.com/blog/string/leetcode-2452-words-within-two-edits-of-dictionary%ef%bf%bc/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 31 Oct 2022 17:25:21 +0000</pubDate>
				<category><![CDATA[String]]></category>
		<category><![CDATA[edit distance]]></category>
		<category><![CDATA[hamming distance]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[string]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9880</guid>

					<description><![CDATA[You are given two string arrays,&#160;queries&#160;and&#160;dictionary. All words in each array comprise of lowercase English letters and have the same length. In one&#160;edit&#160;you can take&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You are given two string arrays,&nbsp;<code>queries</code>&nbsp;and&nbsp;<code>dictionary</code>. All words in each array comprise of lowercase English letters and have the same length.</p>



<p>In one&nbsp;<strong>edit</strong>&nbsp;you can take a word from&nbsp;<code>queries</code>, and change any letter in it to any other letter. Find all words from&nbsp;<code>queries</code>&nbsp;that, after a&nbsp;<strong>maximum</strong>&nbsp;of two edits, equal some word from&nbsp;<code>dictionary</code>.</p>



<p>Return<em>&nbsp;a list of all words from&nbsp;</em><code>queries</code><em>,&nbsp;</em><em>that match with some word from&nbsp;</em><code>dictionary</code><em>&nbsp;after a maximum of&nbsp;<strong>two edits</strong></em>. Return the words in the&nbsp;<strong>same order</strong>&nbsp;they appear in&nbsp;<code>queries</code>.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> queries = ["word","note","ants","wood"], dictionary = ["wood","joke","moat"]
<strong>Output:</strong> ["word","note","wood"]
<strong>Explanation:</strong>
- Changing the 'r' in "word" to 'o' allows it to equal the dictionary word "wood".
- Changing the 'n' to 'j' and the 't' to 'k' in "note" changes it to "joke".
- It would take more than 2 edits for "ants" to equal a dictionary word.
- "wood" can remain unchanged (0 edits) and match the corresponding dictionary word.
Thus, we return ["word","note","wood"].
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> queries = ["yes"], dictionary = ["not"]
<strong>Output:</strong> []
<strong>Explanation:</strong>
Applying any two edits to "yes" cannot make it equal to "not". Thus, we return an empty array.
</pre>



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



<ul class="wp-block-list"><li><code>1 &lt;= queries.length, dictionary.length &lt;= 100</code></li><li><code>n == queries[i].length == dictionary[j].length</code></li><li><code>1 &lt;= n &lt;= 100</code></li><li>All&nbsp;<code>queries[i]</code>&nbsp;and&nbsp;<code>dictionary[j]</code>&nbsp;are composed of lowercase English letters.</li></ul>



<h2 class="wp-block-heading"><strong>Solution: Hamming distance + Brute Force</strong></h2>



<p>For each query word q, check the hamming distance between it and all words in the dictionary.</p>



<p>Time complexity: O(|q|*|d|*n)<br>Space complexity: O(1)</p>



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  vector&lt;string&gt; twoEditWords(vector&lt;string&gt;&amp; queries, vector&lt;string&gt;&amp; dictionary) {
    const int n = queries[0].size();
    auto check = [&amp;](string_view q) {      
      for (const string&amp; w : dictionary) {
        int dist = 0;
        for (int i = 0; i &lt; n &amp;&amp; dist &lt;= 3; ++i)
          dist += q[i] != w[i];
        if (dist &lt;= 2) return true;
      }
      return false;
    };
    vector&lt;string&gt; ans;
    for (const string&amp; q : queries) 
      if (check(q)) ans.push_back(q);
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/string/leetcode-2452-words-within-two-edits-of-dictionary%ef%bf%bc/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2451. Odd String Difference</title>
		<link>https://zxi.mytechroad.com/blog/string/leetcode-2451-odd-string-difference%ef%bf%bc/</link>
					<comments>https://zxi.mytechroad.com/blog/string/leetcode-2451-odd-string-difference%ef%bf%bc/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 31 Oct 2022 16:18:48 +0000</pubDate>
				<category><![CDATA[String]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[difference]]></category>
		<category><![CDATA[easy]]></category>
		<category><![CDATA[string]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9874</guid>

					<description><![CDATA[You are given an array of equal-length strings&#160;words. Assume that the length of each string is&#160;n. Each string&#160;words[i]&#160;can be converted into a&#160;difference integer array&#160;difference[i]&#160;of length&#160;n&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You are given an array of equal-length strings&nbsp;<code>words</code>. Assume that the length of each string is&nbsp;<code>n</code>.</p>



<p>Each string&nbsp;<code>words[i]</code>&nbsp;can be converted into a&nbsp;<strong>difference integer array</strong>&nbsp;<code>difference[i]</code>&nbsp;of length&nbsp;<code>n - 1</code>&nbsp;where&nbsp;<code>difference[i][j] = words[i][j+1] - words[i][j]</code>&nbsp;where&nbsp;<code>0 &lt;= j &lt;= n - 2</code>. Note that the difference between two letters is the difference between their&nbsp;<strong>positions</strong>&nbsp;in the alphabet i.e.&nbsp;the position of&nbsp;<code>'a'</code>&nbsp;is&nbsp;<code>0</code>,&nbsp;<code>'b'</code>&nbsp;is&nbsp;<code>1</code>, and&nbsp;<code>'z'</code>&nbsp;is&nbsp;<code>25</code>.</p>



<ul class="wp-block-list"><li>For example, for the string&nbsp;<code>"acb"</code>, the difference integer array is&nbsp;<code>[2 - 0, 1 - 2] = [2, -1]</code>.</li></ul>



<p>All the strings in words have the same difference integer array,&nbsp;<strong>except one</strong>. You should find that string.</p>



<p>Return<em>&nbsp;the string in&nbsp;</em><code>words</code><em>&nbsp;that has different&nbsp;<strong>difference integer array</strong>.</em></p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> words = ["adc","wzy","abc"]
<strong>Output:</strong> "abc"
<strong>Explanation:</strong> 
- The difference integer array of "adc" is [3 - 0, 2 - 3] = [3, -1].
- The difference integer array of "wzy" is [25 - 22, 24 - 25]= [3, -1].
- The difference integer array of "abc" is [1 - 0, 2 - 1] = [1, 1]. 
The odd array out is [1, 1], so we return the corresponding string, "abc".
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> words = ["aaa","bob","ccc","ddd"]
<strong>Output:</strong> "bob"
<strong>Explanation:</strong> All the integer arrays are [0, 0] except for "bob", which corresponds to [13, -13].
</pre>



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



<ul class="wp-block-list"><li><code>3 &lt;= words.length &lt;= 100</code></li><li><code>n == words[i].length</code></li><li><code>2 &lt;= n &lt;= 20</code></li><li><code>words[i]</code>&nbsp;consists of lowercase English letters.</li></ul>



<h2 class="wp-block-heading"><strong>Solution: Comparing with first string.</strong></h2>



<p>Let us pick words[0] as a reference for comparison, assuming it&#8217;s valid. If we only found one instance say words[i], that is different than words[0], we know that words[i] is bad, otherwise we should see m &#8211; 1 different words which means words[0] itself is bad.</p>



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  string oddString(vector&lt;string&gt;&amp; words) {
    const int m = words.size();
    const int n = words[0].size();
    int count = 0;
    int bad = 0;
    for (int i = 1; i &lt; m; ++i) 
      for (int j = 1; j &lt; n; ++j) {
        if (words[i][j] - words[i][j - 1] 
           != words[0][j] - words[0][j - 1]) {
          ++count;
          bad = i;
          break;
        }
      }
    return words[count == 1 ? bad : 0];
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/string/leetcode-2451-odd-string-difference%ef%bf%bc/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2399. Check Distances Between Same Letters</title>
		<link>https://zxi.mytechroad.com/blog/hashtable/leetcode-2399-check-distances-between-same-letters/</link>
					<comments>https://zxi.mytechroad.com/blog/hashtable/leetcode-2399-check-distances-between-same-letters/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 17 Sep 2022 15:32:25 +0000</pubDate>
				<category><![CDATA[Hashtable]]></category>
		<category><![CDATA[easy]]></category>
		<category><![CDATA[hashtable]]></category>
		<category><![CDATA[string]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9821</guid>

					<description><![CDATA[You are given a&#160;0-indexed&#160;string&#160;s&#160;consisting of only lowercase English letters, where each letter in&#160;s&#160;appears&#160;exactly&#160;twice. You are also given a&#160;0-indexed&#160;integer array&#160;distance&#160;of length&#160;26. Each letter in the alphabet&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You are given a&nbsp;<strong>0-indexed</strong>&nbsp;string&nbsp;<code>s</code>&nbsp;consisting of only lowercase English letters, where each letter in&nbsp;<code>s</code>&nbsp;appears&nbsp;<strong>exactly</strong>&nbsp;<strong>twice</strong>. You are also given a&nbsp;<strong>0-indexed</strong>&nbsp;integer array&nbsp;<code>distance</code>&nbsp;of length&nbsp;<code>26</code>.</p>



<p>Each letter in the alphabet is numbered from&nbsp;<code>0</code>&nbsp;to&nbsp;<code>25</code>&nbsp;(i.e.&nbsp;<code>'a' -&gt; 0</code>,&nbsp;<code>'b' -&gt; 1</code>,&nbsp;<code>'c' -&gt; 2</code>, &#8230; ,&nbsp;<code>'z' -&gt; 25</code>).</p>



<p>In a&nbsp;<strong>well-spaced</strong>&nbsp;string, the number of letters between the two occurrences of the&nbsp;<code>i<sup>th</sup></code>&nbsp;letter is&nbsp;<code>distance[i]</code>. If the&nbsp;<code>i<sup>th</sup></code>&nbsp;letter does not appear in&nbsp;<code>s</code>, then&nbsp;<code>distance[i]</code>&nbsp;can be&nbsp;<strong>ignored</strong>.</p>



<p>Return&nbsp;<code>true</code><em>&nbsp;if&nbsp;</em><code>s</code><em>&nbsp;is a&nbsp;<strong>well-spaced</strong>&nbsp;string, otherwise return&nbsp;</em><code>false</code>.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "abaccb", distance = [1,3,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
<strong>Output:</strong> true
<strong>Explanation:</strong>
- 'a' appears at indices 0 and 2 so it satisfies distance[0] = 1.
- 'b' appears at indices 1 and 5 so it satisfies distance[1] = 3.
- 'c' appears at indices 3 and 4 so it satisfies distance[2] = 0.
Note that distance[3] = 5, but since 'd' does not appear in s, it can be ignored.
Return true because s is a well-spaced string.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "aa", distance = [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
<strong>Output:</strong> false
<strong>Explanation:</strong>
- 'a' appears at indices 0 and 1 so there are zero letters between them.
Because distance[0] = 1, s is not a well-spaced string.
</pre>



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



<ul class="wp-block-list"><li><code>2 &lt;= s.length &lt;= 52</code></li><li><code>s</code>&nbsp;consists only of lowercase English letters.</li><li>Each letter appears in&nbsp;<code>s</code>&nbsp;exactly twice.</li><li><code>distance.length == 26</code></li><li><code>0 &lt;= distance[i] &lt;= 50</code></li></ul>



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



<p>Use a hastable to store the index of first occurrence of each letter.</p>



<p>Time complexity: O(n)<br>Space complexity: O(26)</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 checkDistances(string s, vector&lt;int&gt;&amp; distance) {
    vector&lt;int&gt; m(26, -1);
    for (int i = 0; i &lt; s.length(); ++i) {
      int c = s[i] - 'a';
      if (m[c] &gt;= 0 &amp;&amp; i - m[c] - 1 != distance[c]) return false;
      m[c] = i;
    }
    return true;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/hashtable/leetcode-2399-check-distances-between-same-letters/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
