【LeetCode笔记】Longest Palindromic Substring

来源:互联网 发布:淘宝u站9.9包邮 编辑:程序博客网 时间:2024/06/08 11:45

Three ways of finding the longest palindromi substring:

1.DP

2.Manacher's 

These two algorithm are analyzed thoroughly in articles linked below:

http://leetcode.com/2011/11/longest-palindromic-substring-part-i.html

http://leetcode.com/2011/11/longest-palindromic-substring-part-ii.html 

3.Search twice

This one is common and simple

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

My implementation:

1.DP solution: O(N2) time and O(N2) space (could be improved to use O(N) space)

string palindrome_DP(string s){int maxStart = 0;  //the smallest i among dp[i][j]s == true    <span style="white-space:pre"></span>int maxLen = 1;   //maxLen = j - i + 1, is the max length among dp[i][j]s == trueint n = s.size();vector<vector<bool> > dp(n, vector<bool>(n, false)); //dp[i][j]: s[i..j] is a palindrome or notfor(int i = n - 1; i >= 0; --i)        for(int j = i; j < n; ++j)            if(s[i] == s[j] && (j - i < 2 || dp[i + 1][j - 1])){              /*this equals (s[i] == s[j] && j - i < 2 || s[i] == s[j] && dp[i + 1][j - 1])              s[i] == s[j] && j - i < 2 is to check: when j == i, then s[i] == s[j], then dp[i][i] = true;                   when j == i + 1, if s[i] == s[i+1] then dp[i][i] = true, else false              s[i] == s[j] && dp[i + 1][j - 1] is the dp method             Notice that, s[i] == s[j] && j - i < 2 must be the first condition, or it'll cause memory read problem            */dp[i][j] = true;if(j - i + 1 > maxLen){maxStart = i;           maxLen = j - i + 1;}            }return s.substr(maxStart, maxLen);}



2. Manacher’s algorithm: to find the longest palindrome substring in O(N) time and space

<pre name="code" class="cpp">//Manacher's algorithm: O(N) time and O(N) spacestring preprocessString(string s){string t("#");for(int i = 0; i < s.size(); ++i){t += s[i];t += "#";}return t;}string finder(string s){vector<int> p(s.size(), 1);int mx = 0, id = 0, len = 0, center = 0;for(int i = 0; i < s.size(); ++i){if(mx > i)p[i] = min(p[2 * id - i], mx - i);//expand the panlindrome from the centerwhile (i - p[i] >= 0 && i + p[i] < s.size() && s[i - p[i]] == s[i + p[i]])p[i]++;//update info of reached panlindromeif(i + p[i] > mx){mx = i + p[i]; id = i;   }//record the info of the longest palindromeif(p[i] - 1 > len){len = p[i] - 1;  //len: the length of longest palindromecenter = i;      //center: the center of the longest palindrome}}//generate the longest palindromestring t;  for(int i = len; i > 0; --i)t += s[center + p[center] - 2 * i];return t;}string palindrome_Manacher(string s){s = preprocessString(s);s = finder(s);return s;<span style="font-family: Arial, Helvetica, sans-serif;">}</span>

Time analysis: in the for loop, comparison begins at mx, and mx increases linearly, and elements between the old mx and the new mx wont be compared, so is O(N) method.

3.a simple solution: O(N2) time and O(1) spacego over the string twice to find the odd palindrome and even palindrome

string palindrome_Twice(string s){int n = s.size();if(n <= 1)return s;//n >= 2int maxLen = 1;int maxStart = 0;for(int i = 1; i < n; ++i){//find the longest even palindrome around iint low = i - 1;int high = i;while(low >= 0 && high < n && s[low] == s[high]){if(high - low + 1 > maxLen){maxLen = high - low + 1;maxStart = low;}low--;high++;}//find the longest odd palindrome around ilow = i - 1;high = i + 1;while(low >= 0 && high < n && s[low] == s[high]){if(high - low + 1 > maxLen){maxLen = high - low + 1;maxStart = low;}low--;high++;}}return s.substr(maxStart, maxLen);}


0 0