<?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>Palindrome &#8211; Huahua&#8217;s Tech Road</title>
	<atom:link href="https://zxi.mytechroad.com/blog/tag/palindrome/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>Palindrome &#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-680163f63e34c401929380/] 计数排序：时间：O(n)，空间：O(n) -> O(1) 首尾一起写 [crayon-680163f63e364169608130/]]]></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 2131. Longest Palindrome by Concatenating Two Letter Words</title>
		<link>https://zxi.mytechroad.com/blog/hashtable/leetcode-2131-longest-palindrome-by-concatenating-two-letter-words/</link>
					<comments>https://zxi.mytechroad.com/blog/hashtable/leetcode-2131-longest-palindrome-by-concatenating-two-letter-words/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 09 Jan 2022 12:02:42 +0000</pubDate>
				<category><![CDATA[Hashtable]]></category>
		<category><![CDATA[hashtable]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[Palindrome]]></category>
		<category><![CDATA[string]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9418</guid>

					<description><![CDATA[You are given an array of strings words. Each element of words consists of two lowercase English letters. Create the&#160;longest possible palindrome&#160;by selecting some elements from&#160;words&#160;and concatenating them in&#160;any order.&#8230;]]></description>
										<content:encoded><![CDATA[
<p>You are given an array of strings <code>words</code>. Each element of <code>words</code> consists of <strong>two</strong> lowercase English letters.</p>



<p>Create the&nbsp;<strong>longest possible palindrome</strong>&nbsp;by selecting some elements from&nbsp;<code>words</code>&nbsp;and concatenating them in&nbsp;<strong>any order</strong>. Each element can be selected&nbsp;<strong>at most once</strong>.</p>



<p>Return&nbsp;<em>the&nbsp;<strong>length</strong>&nbsp;of the longest palindrome that you can create</em>. If it is impossible to create any palindrome, return&nbsp;<code>0</code>.</p>



<p>A&nbsp;<strong>palindrome</strong>&nbsp;is a string that reads the same forward and backward.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> words = ["lc","cl","gg"]
<strong>Output:</strong> 6
<strong>Explanation:</strong> One longest palindrome is "lc" + "gg" + "cl" = "lcggcl", of length 6.
Note that "clgglc" is another longest palindrome that can be created.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> words = ["ab","ty","yt","lc","cl","ab"]
<strong>Output:</strong> 8
<strong>Explanation:</strong> One longest palindrome is "ty" + "lc" + "cl" + "yt" = "tylcclyt", of length 8.
Note that "lcyttycl" is another longest palindrome that can be created.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> words = ["cc","ll","xx"]
<strong>Output:</strong> 2
<strong>Explanation:</strong> One longest palindrome is "cc", of length 2.
Note that "ll" is another longest palindrome that can be created, and so is "xx".
</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>words[i].length == 2</code></li><li><code>words[i]</code>&nbsp;consists of lowercase English letters.</li></ul>



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



<p>For any pair of mirrored words, e.g. &#8216;ab&#8217; &lt;-&gt; &#8216;ba&#8217; or &#8216;aa&#8217;  &lt;-&gt; &#8216;aa&#8217;, we can extend the existing longest palindrome, ans += 4.<br>For any unpaired words with same letter, e.g. &#8216;cc&#8217;, we can only use one and put in the middle of the pladrome, ans += 2.</p>



<p>Time complexity: O(n)<br>Space complexity: O(26*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:
  int longestPalindrome(vector&lt;string&gt;&amp; words) {
    int ans = 0;
    int same = 0;
    vector&lt;vector&lt;int&gt;&gt; m(26, vector&lt;int&gt;(26));          
    for (const string&amp; word : words) {      
      const int a = word[0] - 'a';
      const int b = word[1] - 'a';
      if (m[b][a]) {
        --m[b][a];
        ans += 4;
      } else {
        ++m[a][b];
      }
    }
    for (int i = 0; i &lt; 26; ++i)
      if (m[i][i]) {
        ans += 2;
        break;
      }
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/hashtable/leetcode-2131-longest-palindrome-by-concatenating-two-letter-words/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1930. Unique Length-3 Palindromic Subsequences</title>
		<link>https://zxi.mytechroad.com/blog/string/leetcode-1930-unique-length-3-palindromic-subsequences/</link>
					<comments>https://zxi.mytechroad.com/blog/string/leetcode-1930-unique-length-3-palindromic-subsequences/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Fri, 31 Dec 2021 06:28:26 +0000</pubDate>
				<category><![CDATA[String]]></category>
		<category><![CDATA[bitset]]></category>
		<category><![CDATA[hashtable]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[Palindrome]]></category>
		<category><![CDATA[string]]></category>
		<category><![CDATA[subsequence]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9293</guid>

					<description><![CDATA[Given a string&#160;s, return&#160;the number of&#160;unique palindromes of length three&#160;that are a&#160;subsequence&#160;of&#160;s. Note that even if there are multiple ways to obtain the same subsequence,&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Given a string&nbsp;<code>s</code>, return&nbsp;<em>the number of&nbsp;<strong>unique palindromes of length three</strong>&nbsp;that are a&nbsp;<strong>subsequence</strong>&nbsp;of&nbsp;</em><code>s</code>.</p>



<p>Note that even if there are multiple ways to obtain the same subsequence, it is still only counted&nbsp;<strong>once</strong>.</p>



<p>A&nbsp;<strong>palindrome</strong>&nbsp;is a string that reads the same forwards and backwards.</p>



<p>A&nbsp;<strong>subsequence</strong>&nbsp;of a string is a new string generated from the original string with some characters (can be none) deleted without changing the relative order of the remaining characters.</p>



<ul class="wp-block-list"><li>For example,&nbsp;<code>"ace"</code>&nbsp;is a subsequence of&nbsp;<code>"<u>a</u>b<u>c</u>d<u>e</u>"</code>.</li></ul>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "aabca"
<strong>Output:</strong> 3
<strong>Explanation:</strong> The 3 palindromic subsequences of length 3 are:
- "aba" (subsequence of "aabca")
- "aaa" (subsequence of "aabca")
- "aca" (subsequence of "aabca")
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "adc"
<strong>Output:</strong> 0
<strong>Explanation:</strong> There are no palindromic subsequences of length 3 in "adc".
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "bbcbaba"
<strong>Output:</strong> 4
<strong>Explanation:</strong> The 4 palindromic subsequences of length 3 are:
- "bbb" (subsequence of "bbcbaba")
- "bcb" (subsequence of "bbcbaba")
- "bab" (subsequence of "bbcbaba")
- "aba" (subsequence of "bbcbaba")
</pre>



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



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



<h2 class="wp-block-heading"><strong>Solution: Enumerate first <meta charset="utf-8">character of a palindrome</strong></h2>



<p>For a length 3 palindrome, we just need to enumerate the first character c.<br>We found the first and last occurrence of c in original string and scan the middle part to see how many unique characters there.<br><br>e.g. <meta charset="utf-8">aabca<br>Enumerate from a to z, looking for a*a, b*b, &#8230;, z*z.<br>For a*a, <meta charset="utf-8"><span style="text-decoration: underline;"><strong><span class="has-inline-color has-vivid-cyan-blue-color">a</span></strong></span><span class="has-inline-color has-vivid-red-color"><strong>abc</strong></span><span style="text-decoration: underline;"><span class="has-inline-color has-vivid-cyan-blue-color"><strong>a</strong></span></span>, we found first and last a, in between is <meta charset="utf-8"><span class="has-inline-color has-vivid-red-color"><strong>abc</strong></span>, which has 3 unique letters. <br>We can use a hastable or a bitset to track unique letters.</p>



<p>Time complexity: O(26*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:
  int countPalindromicSubsequence(string s) {
    auto count = [&amp;](char c) -&gt; int {
      int l = s.find_first_of(c);
      int r = s.find_last_of(c);
      if (l == string::npos || r == string::npos) return 0;
      bitset&lt;26&gt; m;
      for (int i = l + 1; i &lt; r; ++i)
        m.set(s[i] - 'a');
      return m.count();
    };
    int ans = 0;
    for (char c = 'a'; c &lt;= 'z'; ++c)
      ans += count(c);
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/string/leetcode-1930-unique-length-3-palindromic-subsequences/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 2108. Find First Palindromic String in the Array</title>
		<link>https://zxi.mytechroad.com/blog/string/leetcode-2108-find-first-palindromic-string-in-the-array/</link>
					<comments>https://zxi.mytechroad.com/blog/string/leetcode-2108-find-first-palindromic-string-in-the-array/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Tue, 21 Dec 2021 02:22:10 +0000</pubDate>
				<category><![CDATA[String]]></category>
		<category><![CDATA[easy]]></category>
		<category><![CDATA[Palindrome]]></category>
		<category><![CDATA[string]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=9180</guid>

					<description><![CDATA[Given an array of strings&#160;words, return&#160;the first&#160;palindromic&#160;string in the array. If there is no such string, return&#160;an&#160;empty string&#160;"". A string is&#160;palindromic&#160;if it reads the same&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Given an array of strings&nbsp;<code>words</code>, return&nbsp;<em>the first&nbsp;<strong>palindromic</strong>&nbsp;string in the array</em>. If there is no such string, return&nbsp;<em>an&nbsp;<strong>empty string</strong>&nbsp;</em><code>""</code>.</p>



<p>A string is&nbsp;<strong>palindromic</strong>&nbsp;if it reads the same forward and backward.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> words = ["abc","car","ada","racecar","cool"]
<strong>Output:</strong> "ada"
<strong>Explanation:</strong> The first string that is palindromic is "ada".
Note that "racecar" is also palindromic, but it is not the first.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> words = ["notapalindrome","racecar"]
<strong>Output:</strong> "racecar"
<strong>Explanation:</strong> The first and only string that is palindromic is "racecar".
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> words = ["def","ghi"]
<strong>Output:</strong> ""
<strong>Explanation:</strong> There are no palindromic strings, so the empty string is returned.
</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;= 100</code></li><li><code>words[i]</code>&nbsp;consists only of lowercase English letters.</li></ul>



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



<p>Enumerate each word and check whether it&#8217;s a palindrome or not.</p>



<p>Time complexity: O(n * l)<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 firstPalindrome(vector&lt;string&gt;&amp; words) {
    auto isPalindrome = [](string_view s) {
      size_t l = s.size();
      for (size_t i = 0; i &lt; l / 2; ++i)
        if (s[i] != s[l - i - 1]) return false;
      return true;
    };
    for (const string&amp; word : words)
      if (isPalindrome(word)) return word;
    return &quot;&quot;;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/string/leetcode-2108-find-first-palindromic-string-in-the-array/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1771. Maximize Palindrome Length From Subsequences</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1771-maximize-palindrome-length-from-subsequences/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1771-maximize-palindrome-length-from-subsequences/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 21 Feb 2021 08:45:45 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[Palindrome]]></category>
		<category><![CDATA[string]]></category>
		<category><![CDATA[subsequence]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=8152</guid>

					<description><![CDATA[You are given two strings,&#160;word1&#160;and&#160;word2. You want to construct a string in the following manner: Choose some&#160;non-empty&#160;subsequence&#160;subsequence1&#160;from&#160;word1. Choose some&#160;non-empty&#160;subsequence&#160;subsequence2&#160;from&#160;word2. Concatenate the subsequences:&#160;subsequence1 + subsequence2, to&#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 1771. Maximize Palindrome Length From Subsequences - 刷题找工作 EP386" width="500" height="281" src="https://www.youtube.com/embed/0dbo8C64UFk?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 two strings,&nbsp;<code>word1</code>&nbsp;and&nbsp;<code>word2</code>. You want to construct a string in the following manner:</p>



<ul class="wp-block-list"><li>Choose some&nbsp;<strong>non-empty</strong>&nbsp;subsequence&nbsp;<code>subsequence1</code>&nbsp;from&nbsp;<code>word1</code>.</li><li>Choose some&nbsp;<strong>non-empty</strong>&nbsp;subsequence&nbsp;<code>subsequence2</code>&nbsp;from&nbsp;<code>word2</code>.</li><li>Concatenate the subsequences:&nbsp;<code>subsequence1 + subsequence2</code>, to make the string.</li></ul>



<p>Return&nbsp;<em>the&nbsp;<strong>length</strong>&nbsp;of the longest&nbsp;<strong>palindrome</strong>&nbsp;that can be constructed in the described manner.&nbsp;</em>If no palindromes can be constructed, return&nbsp;<code>0</code>.</p>



<p>A&nbsp;<strong>subsequence</strong>&nbsp;of a string&nbsp;<code>s</code>&nbsp;is a string that can be made by deleting some (possibly none) characters from&nbsp;<code>s</code>&nbsp;without changing the order of the remaining characters.</p>



<p>A&nbsp;<strong>palindrome</strong>&nbsp;is a string that reads the same forward&nbsp;as well as backward.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> word1 = "cacb", word2 = "cbba"
<strong>Output:</strong> 5
<strong>Explanation:</strong> Choose "ab" from word1 and "cba" from word2 to make "abcba", which is a palindrome.</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> word1 = "ab", word2 = "ab"
<strong>Output:</strong> 3
<strong>Explanation:</strong> Choose "ab" from word1 and "a" from word2 to make "aba", which is a palindrome.</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> word1 = "aa", word2 = "bb"
<strong>Output:</strong> 0
<strong>Explanation:</strong> You cannot construct a palindrome from the described method, so return 0.</pre>



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



<ul class="wp-block-list"><li><code>1 &lt;= word1.length, word2.length &lt;= 1000</code></li><li><code>word1</code>&nbsp;and&nbsp;<code>word2</code>&nbsp;consist of lowercase English letters.</li></ul>



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



<figure class="wp-block-image size-large"><a href="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/02/1771-ep386.png"><img fetchpriority="high" decoding="async" width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/02/1771-ep386.png" alt="" class="wp-image-8182" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/02/1771-ep386.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2021/02/1771-ep386-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2021/02/1771-ep386-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/1771-ep386-2.png"><img decoding="async" width="960" height="540" src="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/02/1771-ep386-2.png" alt="" class="wp-image-8183" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2021/02/1771-ep386-2.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2021/02/1771-ep386-2-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2021/02/1771-ep386-2-768x432.png 768w" sizes="(max-width: 960px) 100vw, 960px" /></a></figure>



<p>Similar to <a href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-516-longest-palindromic-subsequence/" data-type="post" data-id="2860">花花酱 LeetCode 516. Longest Palindromic Subsequence</a></p>



<p>Let s = word1 + word2, build dp table on s. We just need to make sure there&#8217;s at least one char from each  string.</p>



<p>Time complexity: O((m+n)^2)<br>Space complexity: O((m+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 longestPalindrome(string word1, string word2) {
    const int l1 = word1.length();
    const int l2 = word2.length();
    string s = word1 + word2;
    const int n = l1 + l2;
    vector&lt;vector&lt;int&gt;&gt; dp(n, vector&lt;int&gt;(n));
    for (int i = 0; i &lt; n; ++i) dp[i][i] = 1;
    for (int l = 2; l &lt;= n; ++l)
      for (int i = 0, j = i + l - 1; j &lt; n; ++i, ++j) {
        if (s[i] == s[j])
          dp[i][j] = dp[i + 1][j - 1] + 2;
        else
          dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);
      }
    
    int ans = 0;
    for (int i = 0; i &lt; l1; ++i)
      for (int j = 0; j &lt; l2; ++j)
        if (word1[i] == word2[j])
          ans = max(ans, dp[i][l1 + j]);
    return ans;
  }
};</pre>
</div></div>



<p>O(m+n) Space complexity</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 longestPalindrome(string word1, string word2) {
    const int l1 = word1.length();
    const int l2 = word2.length();
    string s = word1 + word2;
    const int n = l1 + l2;
    vector&lt;int&gt; dp1(n, 1), dp2(n);
    int ans = 0;
    for (int l = 2; l &lt;= n; ++l) {
      vector&lt;int&gt; dp(n);
      for (int i = 0, j = i + l - 1; j &lt; n; ++i, ++j) {
        if (s[i] == s[j]) {
          dp[i] = dp2[i + 1] + 2;
          if (i &lt; l1 &amp;&amp; j &gt;= l1)
            ans = max(ans, dp[i]);
        } else {
          dp[i] = max(dp1[i + 1], dp1[i]);
        }
      }
      // dp2, dp1 = dp1, dp
      dp1.swap(dp); 
      dp2.swap(dp);
    }
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1771-maximize-palindrome-length-from-subsequences/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1616. Split Two Strings to Make Palindrome</title>
		<link>https://zxi.mytechroad.com/blog/greedy/leetcode-1616-split-two-strings-to-make-palindrome/</link>
					<comments>https://zxi.mytechroad.com/blog/greedy/leetcode-1616-split-two-strings-to-make-palindrome/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 11 Oct 2020 06:05:13 +0000</pubDate>
				<category><![CDATA[Greedy]]></category>
		<category><![CDATA[greedy]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[Palindrome]]></category>
		<category><![CDATA[string]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=7480</guid>

					<description><![CDATA[You are given two strings&#160;a&#160;and&#160;b&#160;of the same length. Choose an index and split both strings&#160;at the same index, splitting&#160;a&#160;into two strings:&#160;aprefix&#160;and&#160;asuffix&#160;where&#160;a = aprefix&#160;+ asuffix, and&#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 1616. Split Two Strings to Make Palindrome - 刷题找工作 EP361" width="500" height="281" src="https://www.youtube.com/embed/9Krnwi6OpnU?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 two strings&nbsp;<code>a</code>&nbsp;and&nbsp;<code>b</code>&nbsp;of the same length. Choose an index and split both strings&nbsp;<strong>at the same index</strong>, splitting&nbsp;<code>a</code>&nbsp;into two strings:&nbsp;<code>a<sub>prefix</sub></code>&nbsp;and&nbsp;<code>a<sub>suffix</sub></code>&nbsp;where&nbsp;<code>a = a<sub>prefix</sub>&nbsp;+ a<sub>suffix</sub></code>, and splitting&nbsp;<code>b</code>&nbsp;into two strings:&nbsp;<code>b<sub>prefix</sub></code>&nbsp;and&nbsp;<code>b<sub>suffix</sub></code>&nbsp;where&nbsp;<code>b = b<sub>prefix</sub>&nbsp;+ b<sub>suffix</sub></code>. Check if&nbsp;<code>a<sub>prefix</sub>&nbsp;+ b<sub>suffix</sub></code>&nbsp;or&nbsp;<code>b<sub>prefix</sub>&nbsp;+ a<sub>suffix</sub></code>&nbsp;forms a palindrome.</p>



<p>When you split a string&nbsp;<code>s</code>&nbsp;into&nbsp;<code>s<sub>prefix</sub></code>&nbsp;and&nbsp;<code>s<sub>suffix</sub></code>, either&nbsp;<code>s<sub>suffix</sub></code>&nbsp;or&nbsp;<code>s<sub>prefix</sub></code>&nbsp;is allowed to be empty. For example, if&nbsp;<code>s = "abc"</code>, then&nbsp;<code>"" + "abc"</code>,&nbsp;<code>"a" + "bc"</code>,&nbsp;<code>"ab" + "c"</code>&nbsp;, and&nbsp;<code>"abc" + ""</code>&nbsp;are valid splits.</p>



<p>Return&nbsp;<code>true</code><em>&nbsp;if it is possible to form</em><em>&nbsp;a palindrome string, otherwise return&nbsp;</em><code>false</code>.</p>



<p><strong>Notice</strong>&nbsp;that&nbsp;<code>x + y</code>&nbsp;denotes the concatenation of strings&nbsp;<code>x</code>&nbsp;and&nbsp;<code>y</code>.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> a = "x", b = "y"
<strong>Output:</strong> true
<strong>Explaination:</strong> If either a or b are palindromes the answer is true since you can split in the following way:
a<sub>prefix</sub> = "", a<sub>suffix</sub> = "x"
b<sub>prefix</sub> = "", b<sub>suffix</sub> = "y"
Then, a<sub>prefix</sub> + b<sub>suffix</sub> = "" + "y" = "y", which is a palindrome.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> a = "abdef", b = "fecab"
<strong>Output:</strong> true
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> a = "ulacfd", b = "jizalu"
<strong>Output:</strong> true
<strong>Explaination:</strong> Split them at index 3:
a<sub>prefix</sub> = "ula", a<sub>suffix</sub> = "cfd"
b<sub>prefix</sub> = "jiz", b<sub>suffix</sub> = "alu"
Then, a<sub>prefix</sub> + b<sub>suffix</sub> = "ula" + "alu" = "ulaalu", which is a palindrome.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> a = "xbdef", b = "xecab"
<strong>Output:</strong> false
</pre>



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



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



<h2 class="wp-block-heading"><strong>Solution: Greedy</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/10/1616-ep361.png" alt="" class="wp-image-7491" srcset="https://zxi.mytechroad.com/blog/wp-content/uploads/2020/10/1616-ep361.png 960w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/10/1616-ep361-300x169.png 300w, https://zxi.mytechroad.com/blog/wp-content/uploads/2020/10/1616-ep361-768x432.png 768w" sizes="auto, (max-width: 960px) 100vw, 960px" /></figure>



<p>Try to match the prefix of A and suffix of B (or the other way) as much as possible and then check whether the remaining part is a palindrome or not.</p>



<p>e.g. A = &#8220;abcxyzzz&#8221;, B = &#8220;uuuvvcba&#8221;<br>A&#8217;s prefix abc matches B&#8217;s suffix cba<br>We just need to check whether &#8220;xy&#8221; or &#8220;vv&#8221; is palindrome or not. <br>The concatenated string &#8220;abc|vvcba&#8221; is a palindrome, left abc is from A and vvcba is from B.</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 checkPalindromeFormation(string a, string b) {
    auto isPalindrome = [](const string&amp; s, int i, int j) {
      while (i &lt; j &amp;&amp; s[i] == s[j]) ++i, --j;        
      return i &gt;= j;
    };
    auto check = [&amp;isPalindrome](const string&amp; a, const string&amp; b) {
      int i = 0;
      int j = a.length() - 1;
      while (a[i] == b[j]) ++i, --j;
      return isPalindrome(a, i, j) || isPalindrome(b, i, j);
    };
    return check(a, b) || check(b, a);
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/greedy/leetcode-1616-split-two-strings-to-make-palindrome/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1332. Remove Palindromic Subsequences</title>
		<link>https://zxi.mytechroad.com/blog/math/leetcode-1332-remove-palindromic-subsequences/</link>
					<comments>https://zxi.mytechroad.com/blog/math/leetcode-1332-remove-palindromic-subsequences/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 26 Jan 2020 18:11:49 +0000</pubDate>
				<category><![CDATA[Math]]></category>
		<category><![CDATA[easy]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[O(n)]]></category>
		<category><![CDATA[Palindrome]]></category>
		<category><![CDATA[subsequence]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=6142</guid>

					<description><![CDATA[Given a string&#160;s&#160;consisting only of&#160;letters&#160;'a'&#160;and&#160;'b'. In a single step you can remove one&#160;palindromic&#160;subsequence&#160;from&#160;s. Return the minimum number of steps to make the given string empty.&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Given a string&nbsp;<code>s</code>&nbsp;consisting only of&nbsp;letters&nbsp;<code>'a'</code>&nbsp;and&nbsp;<code>'b'</code>. In a single step you can remove one&nbsp;palindromic&nbsp;<strong>subsequence</strong>&nbsp;from&nbsp;<code>s</code>.</p>



<p>Return the minimum number of steps to make the given string empty.</p>



<p>A string is a subsequence of a given string, if it is generated by deleting some characters of a given string without changing its order.</p>



<p>A string is called palindrome if is one that reads the same backward as well as forward.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "ababa"
<strong>Output:</strong> 1
<strong>Explanation:</strong> String is already palindrome
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "abb"
<strong>Output:</strong> 2
<strong>Explanation:</strong> "<strong>a</strong>bb" -&gt; "<strong>bb</strong>" -&gt; "". 
Remove palindromic subsequence "a" then "bb".
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "baabb"
<strong>Output:</strong> 2
<strong>Explanation:</strong> "<strong>baa</strong>b<strong>b</strong>" -&gt; "b" -&gt; "". 
Remove palindromic subsequence "baab" then "b".
</pre>



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



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



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



<ul class="wp-block-list"><li><code>0 &lt;= s.length &lt;= 1000</code></li><li><code>s</code>&nbsp;only consists of letters &#8216;a&#8217; and &#8216;b&#8217;</li></ul>



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



<p>if s is empty => 0 step<br>if s is a palindrome => 1 step<br>Otherwise, 2 steps&#8230;<br>1. delete all the as<br>2. delete all the bs</p>



<p>Time complexity: O(n)<br>Space complexity: O(n) / 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 removePalindromeSub(string s) {
    if (s.empty()) return 0;
    if (s == string(rbegin(s), rend(s))) return 1;
    return 2;
  }
};</pre>
</div></div>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/math/leetcode-1332-remove-palindromic-subsequences/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1328. Break a Palindrome</title>
		<link>https://zxi.mytechroad.com/blog/greedy/leetcode-1328-break-a-palindrome/</link>
					<comments>https://zxi.mytechroad.com/blog/greedy/leetcode-1328-break-a-palindrome/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 26 Jan 2020 16:41:10 +0000</pubDate>
				<category><![CDATA[Greedy]]></category>
		<category><![CDATA[greedy]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[O(n)]]></category>
		<category><![CDATA[Palindrome]]></category>
		<category><![CDATA[string]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=6127</guid>

					<description><![CDATA[Given a palindromic string&#160;palindrome, replace&#160;exactly one&#160;character by any lowercase English letter so that the string becomes the lexicographically smallest possible string that&#160;isn&#8217;t&#160;a palindrome. After doing&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Given a palindromic string&nbsp;<code>palindrome</code>, replace&nbsp;<strong>exactly one</strong>&nbsp;character by any lowercase English letter so that the string becomes the lexicographically smallest possible string that&nbsp;<strong>isn&#8217;t</strong>&nbsp;a palindrome.</p>



<p>After doing so, return the final string.&nbsp; If there is no way to do so, return the empty string.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> palindrome = "abccba"
<strong>Output:</strong> "aaccba"
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> palindrome = "a"
<strong>Output:</strong> ""
</pre>



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



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



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



<p>For the first half of the string, replace the first non &#8216;a&#8217; character to &#8216;a&#8217;.</p>



<p>e.g. abcdcba =&gt; aacdcba</p>



<p>If not found which means the the entire string is &#8216;a&#8217; expect the middle one if the length is odd, like aa or aba, replace the last character to &#8216;b&#8217;.</p>



<p>aa =&gt; ab<br>aba =&gt; abb</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:
  string breakPalindrome(string palindrome) {
    const int n = palindrome.length();
    if (n == 1) return &quot;&quot;;
    for (int i = 0; i &lt; n / 2; ++i) {
      if (palindrome[i] != 'a') {
        palindrome[i] = 'a';
        return palindrome;
      }
    }
    palindrome.back() = 'b';
    return palindrome;
  }
};</pre>
</div></div>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/greedy/leetcode-1328-break-a-palindrome/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1312. Minimum Insertion Steps to Make a String Palindrome</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1312-minimum-insertion-steps-to-make-a-string-palindrome/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1312-minimum-insertion-steps-to-make-a-string-palindrome/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 05 Jan 2020 05:57:25 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[Palindrome]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=6046</guid>

					<description><![CDATA[Given a string&#160;s. In one step you can insert any character at any index of the string. Return&#160;the minimum number of steps&#160;to make&#160;s&#160;palindrome. A&#160;Palindrome String&#160;is&#8230;]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-4-3 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="花花酱 LeetCode 1312. Minimum Insertion Steps to Make a String Palindrome - 刷题找工作 EP293" width="500" height="375" src="https://www.youtube.com/embed/XNWz9xbX8F0?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>Given a string&nbsp;<code>s</code>. In one step you can insert any character at any index of the string.</p>



<p>Return&nbsp;<em>the minimum number of steps</em>&nbsp;to make&nbsp;<code>s</code>&nbsp;palindrome.</p>



<p>A&nbsp;<strong>Palindrome String</strong>&nbsp;is one that reads the same backward as well as forward.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "zzazz"
<strong>Output:</strong> 0
<strong>Explanation:</strong> The string "zzazz" is already palindrome we don't need any insertions.
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "mbadm"
<strong>Output:</strong> 2
<strong>Explanation:</strong> String can be "mbdadbm" or "mdbabdm".
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "leetcode"
<strong>Output:</strong> 5
<strong>Explanation:</strong> Inserting 5 characters the string becomes "leetcodocteel".
</pre>



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



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



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



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



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



<ul class="wp-block-list"><li><code>1 &lt;= s.length &lt;= 500</code></li><li>All characters of&nbsp;<code>s</code>&nbsp;are lower case English letters.</li></ul>



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



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



<p>dp[i][j] := min chars to insert<br>dp[j][j] =  dp[i-1][j+1] if s[i] == s[j]  else min(dp[i+1][j] , dp[i][j-1]) + 1<br>base case: dp[i][i] = 0<br>ans: dp[0][n-1]</p>



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  int minInsertions(string s) {
    const int n = s.length();
    vector&lt;vector&lt;int&gt;&gt; dp(n, vector&lt;int&gt;(n));
    
    for (int l = 2; l &lt;= n; ++l)
      for (int i = 0, j = l - 1; j &lt; n; ++i, ++j)        
        dp[i][j] = s[i] == s[j] ? dp[i + 1][j - 1] : min(dp[i + 1][j], dp[i][j - 1]) + 1;                        
    return dp[0][n - 1];
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1312-minimum-insertion-steps-to-make-a-string-palindrome/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 132. Palindrome Partitioning II</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-132-palindrome-partitioning-ii/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-132-palindrome-partitioning-ii/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sat, 07 Dec 2019 21:01:04 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[Palindrome]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=5929</guid>

					<description><![CDATA[Given a string&#160;s, partition&#160;s&#160;such that every substring of the partition is a palindrome. Return the minimum cuts needed for a palindrome partitioning of&#160;s. Example: Input:&#160;"aab"&#8230;]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-4-3 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="花花酱 LeetCode 132. Palindrome Partitioning II - 刷题找工作 EP281" width="500" height="375" src="https://www.youtube.com/embed/kTCymFbU2ok?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>Given a string&nbsp;<em>s</em>, partition&nbsp;<em>s</em>&nbsp;such that every substring of the partition is a palindrome.</p>



<p>Return the minimum cuts needed for a palindrome partitioning of&nbsp;<em>s</em>.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong>&nbsp;"aab"
<strong>Output:</strong> 1
<strong>Explanation:</strong> The palindrome partitioning ["aa","b"] could be produced using 1 cut.</pre>



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



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



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



<p>dp[i] := min cuts of s[0~i]<br>dp[i] = min{dp[j] + 1} if s[j+1~i] is a palindrome.</p>



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  int minCut(string s) {
    const int n = s.length();
    // valid[i][j] = 1 if s[i~j] is palindrome, otherwise 0
    vector&lt;vector&lt;int&gt;&gt; valid(n, vector&lt;int&gt;(n, 1));
    
    // dp[i] = min cuts of s[0~i] 
    vector&lt;int&gt; dp(n, n);
    
    for (int l = 2; l &lt;= n; ++l)
      for (int i = 0, j = i + l - 1; j &lt; n; ++i, ++j)
        valid[i][j] = s[i] == s[j] &amp;&amp; valid[i + 1][j - 1];
    
    for (int i = 0; i &lt; n; ++i) {      
      if (valid[0][i]) {
        dp[i] = 0;
        continue;
      }
      for (int j = 0; j &lt; i; ++j)
        if (valid[j + 1][i])
          dp[i] = min(dp[i], dp[j] + 1);      
    }
    return dp[n - 1];
  }
};</pre>
</div></div>



<p>DP v2</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 minCut(string s) {
    const int n = s.length();        
    // dp[i] = min cuts of s[0~i] 
    vector&lt;int&gt; dp(n, n);    
    for (int m = 0; m &lt; n; ++m)      
      for (int d = 0; d &lt;= 1; ++d)
        for (int i = m, j = m + d; i &gt;= 0 &amp;&amp; j &lt; n &amp;&amp; s[i] == s[j]; --i, ++j)
          dp[j] = min(dp[j], (i ? (dp[i - 1] + 1) : 0));    
    return dp[n - 1];
  }
};</pre>
</div></div>



<h2 class="wp-block-heading"><strong>Related Problems</strong></h2>



<p>131. <a href="https://zxi.mytechroad.com/blog/searching/leetcode-131-palindrome-partitioning/">https://zxi.mytechroad.com/blog/searching/leetcode-131-palindrome-partitioning/</a><br>1278. <a href="https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1278-palindrome-partitioning-iii/">https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-1278-palindrome-partitioning-iii/</a></p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-132-palindrome-partitioning-ii/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 131. Palindrome Partitioning</title>
		<link>https://zxi.mytechroad.com/blog/searching/leetcode-131-palindrome-partitioning/</link>
					<comments>https://zxi.mytechroad.com/blog/searching/leetcode-131-palindrome-partitioning/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Thu, 10 Oct 2019 15:28:55 +0000</pubDate>
				<category><![CDATA[Search]]></category>
		<category><![CDATA[DFS]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[Palindrome]]></category>
		<category><![CDATA[string]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=5749</guid>

					<description><![CDATA[Given a string&#160;s, partition&#160;s&#160;such that every substring of the partition is a palindrome. Return all possible palindrome partitioning of&#160;s. Example: Input:&#160;"aab" Output: [ ["aa","b"], ["a","a","b"]&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Given a string&nbsp;<em>s</em>, partition&nbsp;<em>s</em>&nbsp;such that every substring of the partition is a palindrome.</p>



<p>Return all possible palindrome partitioning of&nbsp;<em>s</em>.</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong>&nbsp;"aab"
<strong>Output:</strong>
[
  ["aa","b"],
  ["a","a","b"]
]</pre>



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



<p>dp[i] := ans of str[0:i]<br>dp[j] = { x + str[i:len] for x in dp[i] }, 0 &lt;= i &lt; len</p>



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
bool isPalindrome(const string&amp; s) {
  const int n = s.length();
  for (int i = 0; i &lt; n / 2; ++i)
    if (s[i] != s[n - 1 - i]) return false;
  return true;
}

class Solution {
public:
  vector&lt;vector&lt;string&gt;&gt; partition(string s) {    
    int n = s.length();    
    vector&lt;vector&lt;vector&lt;string&gt;&gt;&gt; dp(n + 1);    
    for (int len = 1; len &lt;= n; ++len) {
      for (int i = 0; i &lt; len; ++i) {
        string right = s.substr(i, len - i);
        if (!isPalindrome(right)) continue;
        if (i == 0) dp[len].push_back({right});
        for (const auto&amp; p : dp[i]) {
          dp[len].push_back(p);
          dp[len].back().push_back(right);
        }        
      }
    }
    return dp[n];
  } 
};</pre>
</div></div>



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



<p> Time complexity: O(2^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
bool isPalindrome(const string&amp; s, int l, int r) {
  while (l &lt; r)
    if (s[l++] != s[r--]) return false;  
  return true;
}

class Solution {
public:
  vector&lt;vector&lt;string&gt;&gt; partition(string s) {    
    int n = s.length();    
    vector&lt;vector&lt;string&gt;&gt; ans;
    vector&lt;string&gt; cur;
    function&lt;void(int)&gt; dfs = [&amp;](int start) {
      if (start == n) {
        ans.push_back(cur);
        return;
      }
      
      for (int i = start; i &lt; n; ++i) {
        if (!isPalindrome(s, start, i)) continue;
        cur.push_back(s.substr(start, i - start + 1));
        dfs(i + 1);
        cur.pop_back();
      }
    };
    dfs(0);
    return ans;
  } 
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/searching/leetcode-131-palindrome-partitioning/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1177. Can Make Palindrome from Substring</title>
		<link>https://zxi.mytechroad.com/blog/hashtable/leetcode-1177-can-make-palindrome-from-substring/</link>
					<comments>https://zxi.mytechroad.com/blog/hashtable/leetcode-1177-can-make-palindrome-from-substring/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Mon, 02 Sep 2019 00:56:36 +0000</pubDate>
				<category><![CDATA[Hashtable]]></category>
		<category><![CDATA[frequency]]></category>
		<category><![CDATA[hashtable]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[Palindrome]]></category>
		<category><![CDATA[prefix sum]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=5516</guid>

					<description><![CDATA[Given a string&#160;s, we make queries on substrings of&#160;s. For each query&#160;queries[i] = [left, right, k], we may&#160;rearrange&#160;the substring&#160;s[left], ..., s[right], and then choose&#160;up to&#160;k&#160;of&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Given a string&nbsp;<code>s</code>, we make queries on substrings of&nbsp;<code>s</code>.</p>



<p>For each query&nbsp;<code>queries[i] = [left, right, k]</code>, we may&nbsp;<strong>rearrange</strong>&nbsp;the substring&nbsp;<code>s[left], ..., s[right]</code>, and then choose&nbsp;<strong>up to</strong>&nbsp;<code>k</code>&nbsp;of them to replace with any lowercase English letter.&nbsp;</p>



<p>If the substring&nbsp;is possible to be a&nbsp;palindrome string after the operations above, the result of the query is&nbsp;<code>true</code>.&nbsp;Otherwise, the result&nbsp;is&nbsp;<code>false</code>.</p>



<p>Return an array&nbsp;<code>answer[]</code>, where&nbsp;<code>answer[i]</code>&nbsp;is the result of the&nbsp;<code>i</code>-th query&nbsp;<code>queries[i]</code>.</p>



<p>Note that: Each letter is counted&nbsp;<strong>individually</strong>&nbsp;for replacement so&nbsp;if for example&nbsp;<code>s[left..right] = "aaa"</code>, and&nbsp;<code>k = 2</code>, we can only replace two of the letters.&nbsp; (Also, note that the initial string&nbsp;<code>s</code>&nbsp;is never modified by any query.)</p>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> s = "abcda", queries = [[3,3,0],[1,2,0],[0,3,1],[0,3,2],[0,4,1]]
<strong>Output:</strong> [true,false,false,true,true]
<strong>Explanation:</strong>
queries[0] : substring = "d", is palidrome.
queries[1] :&nbsp;substring = "bc", is not palidrome.
queries[2] :&nbsp;substring = "abcd", is not palidrome after replacing only 1 character.
queries[3] :&nbsp;substring = "abcd", could be changed to "abba" which is palidrome. Also this can be changed to "baab" first rearrange it "bacd" then replace "cd" with "ab".
queries[4] :&nbsp;substring = "abcda",&nbsp;could be changed to "abcba" which is palidrome.
</pre>



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



<ul class="wp-block-list"><li><code>1 &lt;= s.length,&nbsp;queries.length&nbsp;&lt;= 10^5</code></li><li><code>0 &lt;= queries[i][0] &lt;= queries[i][1] &lt;&nbsp;s.length</code></li><li><code>0 &lt;= queries[i][2] &lt;= s.length</code></li><li><code>s</code>&nbsp;only contains lowercase English letters.</li></ul>



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



<p>Compute the prefix frequency of each characters, then we can efficiently compute the frequency of each characters in the substring in O(1) time. Count the number odd frequency characters o, we can convert it to a palindrome if o / 2 &lt;= k.</p>



<p>Time complexity: <br>preprocessing: O(n)<br>Query: O(1)<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;bool&gt; canMakePaliQueries(string s, vector&lt;vector&lt;int&gt;&gt;&amp; queries) {
    vector&lt;bool&gt; ans;
    int n = s.length();
    vector&lt;vector&lt;int&gt;&gt; f(n + 1, vector&lt;int&gt;(26));
    for (int i = 0; i &lt; n; ++i) {
      ++f[i][s[i] - 'a'];
      f[i + 1] = f[i];
    }
    for (const auto&amp; q : queries) {      
      int l = q[0];
      int r = q[1];
      int k = q[2];      
      int o = 0;
      for (int i = 0; i &lt; 26; ++i) {
        int c = f[r][i] - (l == 0 ? 0 : f[l - 1][i]);        
        o += c % 2;
      }
      ans.push_back(o / 2 &lt;= k);
    }
    return ans;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/hashtable/leetcode-1177-can-make-palindrome-from-substring/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 1147. Longest Chunked Palindrome Decomposition</title>
		<link>https://zxi.mytechroad.com/blog/string/leetcode-1147-longest-chunked-palindrome-decomposition/</link>
					<comments>https://zxi.mytechroad.com/blog/string/leetcode-1147-longest-chunked-palindrome-decomposition/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Sun, 04 Aug 2019 18:31:19 +0000</pubDate>
				<category><![CDATA[Greedy]]></category>
		<category><![CDATA[String]]></category>
		<category><![CDATA[greedy]]></category>
		<category><![CDATA[hard]]></category>
		<category><![CDATA[Palindrome]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=5393</guid>

					<description><![CDATA[Return the largest possible&#160;k&#160;such that there exists&#160;a_1, a_2, ..., a_k&#160;such that: Each&#160;a_i&#160;is a non-empty string; Their concatenation&#160;a_1 + a_2 + ... + a_k&#160;is equal to&#160;text;&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Return the largest possible&nbsp;<code>k</code>&nbsp;such that there exists&nbsp;<code>a_1, a_2, ..., a_k</code>&nbsp;such that:</p>



<ul class="wp-block-list"><li>Each&nbsp;<code>a_i</code>&nbsp;is a non-empty string;</li><li>Their concatenation&nbsp;<code>a_1 + a_2 + ... + a_k</code>&nbsp;is equal to&nbsp;<code>text</code>;</li><li>For all&nbsp;<code>1 &lt;= i &lt;= k</code>,&nbsp;&nbsp;<code>a_i = a_{k+1 - i}</code>.</li></ul>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> text = "ghiabcdefhelloadamhelloabcdefghi"
<strong>Output:</strong> 7
<strong>Explanation:</strong> We can split the string on "(ghi)(abcdef)(hello)(adam)(hello)(abcdef)(ghi)".
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> text = "merchant"
<strong>Output:</strong> 1
<strong>Explanation:</strong> We can split the string on "(merchant)".
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> text = "antaprezatepzapreanta"
<strong>Output:</strong> 11
<strong>Explanation:</strong> We can split the string on "(a)(nt)(a)(pre)(za)(tpe)(za)(pre)(a)(nt)(a)".
</pre>



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



<pre class="wp-block-preformatted;crayon:false"><strong>Input:</strong> text = "aaa"
<strong>Output:</strong> 3
<strong>Explanation:</strong> We can split the string on "(a)(a)(a)".</pre>



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



<p>Break the string when the shortest palindrome is found.<br>prefer to use string_view</p>



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



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

<pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua, 0 ms, 8.7 ms
class Solution {
public:
  int longestDecomposition(string_view text) {    
    const int n = text.length();
    if (n == 0) return 0;
    for (int l = 1; l &lt;= n / 2; ++l) {
      if (text.substr(0, l) == text.substr(n - l)) 
        return 2 + longestDecomposition(text.substr(l, n - 2 * l));
    }
    return 1;
  }
};</pre>
</div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/string/leetcode-1147-longest-chunked-palindrome-decomposition/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 9. Palindrome Number</title>
		<link>https://zxi.mytechroad.com/blog/math/leetcode-9-palindrome-number/</link>
					<comments>https://zxi.mytechroad.com/blog/math/leetcode-9-palindrome-number/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Thu, 13 Sep 2018 01:48:10 +0000</pubDate>
				<category><![CDATA[Math]]></category>
		<category><![CDATA[easy]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[Palindrome]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=3934</guid>

					<description><![CDATA[Problem Determine whether an integer is a palindrome. An integer is a palindrome when it reads the same backward as forward. Example 1: Input: 121 Output: true Example 2:&#8230;]]></description>
										<content:encoded><![CDATA[<h1><strong>Problem</strong></h1>
<p>Determine whether an integer is a palindrome. An integer is a palindrome when it reads the same backward as forward.</p>
<p><strong>Example 1:</strong></p>
<pre class="crayon:false"><strong>Input:</strong> 121
<strong>Output:</strong> true
</pre>
<p><strong>Example 2:</strong></p>
<pre class="crayon:false"><strong>Input:</strong> -121
<strong>Output:</strong> false
<strong>Explanation:</strong> From left to right, it reads -121. From right to left, it becomes 121-. Therefore it is not a palindrome.
</pre>
<p><strong>Example 3:</strong></p>
<pre class="crayon:false"><strong>Input:</strong> 10
<strong>Output:</strong> false
<strong>Explanation:</strong> Reads 01 from right to left. Therefore it is not a palindrome.
</pre>
<p><strong>Follow up:</strong></p>
<p>Could you solve it without converting the integer to a string?</p>
<h1><strong>Solution 1: Convert to string (cheating)</strong></h1>
<p>Time complexity: O(log10(x))</p>
<p>Space complexity: O(log10(x))</p>
<p><div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">
</p><pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  bool isPalindrome(int x) {
    string s = to_string(x);    
    return s == string(rbegin(s), rend(s));
  }
};</pre><p></div></div></p>
<h1><strong>Solution 2: Digit by Digit</strong></h1>
<p>Every time we compare the first and last digits of x, if they are not the same, return false. Otherwise, remove first and last digit and continue this process.</p>
<p>How can we achieve that via int math?</p>
<p>e.g. x = 9999, t = pow((10, int)log10(x)) = 1000</p>
<p>first digit: x / t, last digit: x % 10</p>
<p>then x = (x &#8211; x / t * t) / 10 removes first and last digits.</p>
<p>t /= 100 since we removed two digits.</p>
<p>x / t = 9 = 9 = x % 10, 9999 =&gt; 99</p>
<p>9 = 9, 99 =&gt; &#8220;&#8221;</p>
<p>Time complexity: O(log10(x) / 2)</p>
<p>Space complexity: O(1)</p>
<p><div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">
</p><pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua
class Solution {
public:
  bool isPalindrome(int x) {
    if (x &lt; 0) return false;
    int d = static_cast&lt;int&gt;(log10(x) + 1);
    int t = pow(10, d - 1);
    for (int i = 0; i &lt; d / 2; ++i) {     
      if (x / t != x % 10) return false;
      x = (x - x / t * t) / 10;
      t /= 100;     
    }
    return true;
  }
};</pre><p></div></div></p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/math/leetcode-9-palindrome-number/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>花花酱 LeetCode 5. Longest Palindromic Substring</title>
		<link>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-5-longest-palindromic-substring/</link>
					<comments>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-5-longest-palindromic-substring/#respond</comments>
		
		<dc:creator><![CDATA[zxi]]></dc:creator>
		<pubDate>Wed, 12 Sep 2018 07:45:12 +0000</pubDate>
				<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[dp]]></category>
		<category><![CDATA[longest]]></category>
		<category><![CDATA[medium]]></category>
		<category><![CDATA[O(n^2)]]></category>
		<category><![CDATA[Palindrome]]></category>
		<category><![CDATA[string]]></category>
		<guid isPermaLink="false">https://zxi.mytechroad.com/blog/?p=3917</guid>

					<description><![CDATA[Problem Given a string&#160;s, find the longest palindromic substring in&#160;s. You may assume that the maximum length of&#160;s&#160;is 1000. Example 1: Input: "babad" Output: "bab"&#8230;]]></description>
										<content:encoded><![CDATA[<h1><strong>Problem</strong></h1>
<p>Given a string&nbsp;<strong>s</strong>, find the longest palindromic substring in&nbsp;<strong>s</strong>. You may assume that the maximum length of&nbsp;<strong>s</strong>&nbsp;is 1000.</p>
<p><strong>Example 1:</strong></p>
<pre class="crayon:false"><strong>Input:</strong> "babad"
<strong>Output:</strong> "bab"
<strong>Note:</strong> "aba" is also a valid answer.
</pre>
<p><strong>Example 2:</strong></p>
<pre class="crayon:false"><strong>Input:</strong> "cbbd"
<strong>Output:</strong> "bb"
</pre>
<h1><strong>Solution: DP</strong></h1>
<p>Try all possible i and find the longest palindromic string whose center is i (odd case) and i / i + 1 (even case).</p>
<p>Time complexity: O(n^2)</p>
<p>Space complexity: O(1)</p>
<p><div class="responsive-tabs">
<h2 class="tabtitle">C++</h2>
<div class="tabcontent">
</p><pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua, 16 ms, 8.7 MB
class Solution {
public:
  string longestPalindrome(string s) {
    const int n = s.length();
    auto getLen = [&amp;](int l, int r) {
      while (l &gt;= 0 &amp;&amp; r &lt; n 
             &amp;&amp; s[l] == s[r]) {
        --l;
        ++r;
      }
      return r - l - 1;
    };
    int len = 0;
    int start = 0;
    for (int i = 0; i &lt; n; ++i) {
      int cur = max(getLen(i, i), 
                    getLen(i, i + 1));
      if (cur &gt; len) {
        len = cur;
        start = i - (len - 1) / 2;
      }
    }
    return s.substr(start, len);
  }
};</pre><p></div></div></p>
<p><div class="responsive-tabs">
<h2 class="tabtitle">Java</h2>
<div class="tabcontent">
</p><pre class="urvanov-syntax-highlighter-plain-tag">// Author: Huahua, 6 ms， 36.5 MB
class Solution {
  public String longestPalindrome(String s) {
    int len = 0;
    int start = 0;
    for (int i = 0; i &lt; s.length(); ++i) {
      int cur = Math.max(getLen(s, i, i), 
                         getLen(s, i, i + 1));
      if (cur &gt; len) {
        len = cur;
        start = i - (cur - 1) / 2;
      }
    }
    return s.substring(start, start + len);
  }
  
  private int getLen(String s, int l, int r) {
    while (l &gt;= 0 &amp;&amp; r &lt; s.length() 
           &amp;&amp; s.charAt(l) == s.charAt(r)) {
      --l;
      ++r;
    }
    return r - l - 1;
  }
}</pre><p></div></div></p>
<p><div class="responsive-tabs">
<h2 class="tabtitle">Python3</h2>
<div class="tabcontent">
</p><pre class="urvanov-syntax-highlighter-plain-tag"># Author: Huahua, 812 ms, 12.7MB
class Solution:
  def longestPalindrome(self, s: str) -&gt; str:
    n = len(s)
    def getLen(l, r):
      while l &gt;= 0 and r &lt; n and s[l] == s[r]:
        l -= 1
        r += 1
      return r - l - 1
    
    start = 0
    length = 0    
    for i in range(n):      
      cur = max(getLen(i, i),
                getLen(i, i + 1))
      if cur &lt;= length: continue
      length = cur
      start = i - (cur - 1) // 2
    return s[start : start + length]</pre><p></div></div></p>
]]></content:encoded>
					
					<wfw:commentRss>https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-5-longest-palindromic-substring/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
