leetcode 回文系列 Palindrome

来源:互联网 发布:淘宝买伟哥专用工具 编辑:程序博客网 时间:2024/05/18 18:55

首先是经典的最长回文子串,Manacher给出了线性的算法。


Longest Palindromic Substring

 
AC Rate: 859/3674

Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, 

and there exists one unique longest palindromic substring.

该算法在我另一篇博客中有介绍(传送门 http://blog.csdn.net/jiaowopan/article/details/9243195  ),这里就不再说明了。直接上代码


class Solution {public:    string longestPalindrome(string s) {        // Start typing your C/C++ solution below        // DO NOT write int main() function        //use Manacher's Algorithm O(n)        if(s.empty()) return s;        int len = s.length();int i;        //construct new string        ostringstream ss;        ss << "^";        for(i = 0; i < len; ++i){            ss<<"#"<<s[i];        }        ss<<"#$";        string newstr = ss.str();        len = newstr.length();        vector<int> p(len,1);        int mx(0),id(0),ans(1),center(0);        for(i = 1; i < len-1; ++i){            p[i] = (mx > i) ? min(p[2 * id - i], mx - i) : 1;            while(newstr[i - p[i]] == newstr[i + p[i]]) p[i]++;            if(i + p[i] > mx){//update mx and id                mx = i + p[i];                id = i;            }            if(p[i] > ans){//update ans and center                center = i;                ans = p[i];            }        }        ans -= 1;        return s.substr((center - ans - 1) / 2, ans);    }};


Valid Palindrome

 
AC Rate: 1046/4724

Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases.

For example,
"A man, a plan, a canal: Panama" is a palindrome.
"race a car" is not a palindrome.

Note:
Have you consider that the string might be empty? This is a good question to ask during an interview.

For the purpose of this problem, we define empty string as valid palindrome.


class Solution {public:    bool isPalindrome(string s) {        // Note: The Solution object is instantiated only once and is reused by each test case.        /*        if(s.empty()) return true;        stringstream ss;        for(int i = 0; i < s.length(); ++i){            if(isdigit(s[i]))                ss<<s[i];            else if(isupper(s[i])){                ss<<char(s[i]+32);            }            else if(islower(s[i])){                ss<<s[i];            }        }        string cleanstr = ss.str();        int len = cleanstr.length();        if(0 == len)            return true;        int left = 0, right = len -1;        while(left < right){            if(cleanstr[left++] != cleanstr[right--])                    return false;        }        return true;        */        //don't use extra string space        if(s.empty())   return true;        int len = s.length();        int i(0), j(len-1);        while( i < j){            if(!isalnum(s[i])) ++i;            else if(!isalnum(s[j])) --j;            else{                if(isupper(s[i])) s[i] += 32;                if(isupper(s[j])) s[j] += 32;                if(s[i] != s[j]) return false;                 ++i;--j;            }         }        return true;    }};

Palindrome Number

 
AC Rate: 1028/3305

Determine whether an integer is a palindrome. Do this without extra space.

click to show spoilers.

Some hints:

Could negative integers be palindromes? (ie, -1)

If you are thinking of converting the integer to string, note the restriction of using extra space.

You could also try reversing an integer. However, if you have solved the problem "Reverse Integer", you know that the reversed integer might overflow. How would you handle such case?

There is a more generic way of solving this problem.

不使用额外空间是这个题的一个点,因此就要想办法获取第一位和最后一位。

class Solution {public:    bool isPalindrome(int x) {        // Note: The Solution object is instantiated only once and is reused by each test case.        if(x < 0) return false;        int div = 1;        while(x / div >= 10)            div *= 10;        while(x){            int l = x /div;            int r = x % 10;            if(l != r)  return false;            x = (x % div) / 10;            div /= 100;        }        return true;    }};

Palindrome Partitioning

 
AC Rate: 807/3208

Given a string s, partition s such that every substring of the partition is a palindrome.

Return all possible palindrome partitioning of s.

For example, given s = "aab",
Return

  [    ["aa","b"],    ["a","a","b"]  ]

这个题对时间的限制要求在判断是否是回文串的时候打个表记录一下,否则会超时。

用dp的思路去打表求ispa[i][j] , 然后用回溯得到所有可能的解。

class Solution {public:    vector<vector<string>> partition(string s) {        // Note: The Solution object is instantiated only once and is reused by each test case.        int len = s.length();        if(0 == len) return vector<vector<string> >();        vector<vector<bool> > ispa(len,vector<bool>(len,false));        //build ispa with DP        for(int i = 1; i <= len; ++i){            for(int j = 0; j + i -1 < len; ++j){                int k = j + i - 1;                if(1 == i) ispa[j][j] = true;                else if(2 == i) ispa[j][k] = (s[j] == s[k]);                else                    ispa[j][k] = ( s[j] == s[k] && ispa[j+1][k-1] );            }        }        //backtracking to get solution        vector<string> tmp;        vector<vector<string> > ret;        helper(s,0,tmp,ret,ispa);        return ret;    }    void helper(const string &s, int pos, vector<string> &solution, vector<vector<string> > &result,const vector<vector<bool> > &ispa){        if(pos == s.length()){            result.push_back(solution);            return;        }        for(int i = pos; i < s.length(); ++i){            if(ispa[pos][i]){                solution.push_back(s.substr(pos,i-pos+1));                helper(s,i+1,solution,result,ispa);                solution.pop_back();            }        }        return;    }};

Palindrome Partitioning II

 
AC Rate: 765/4671

Given a string s, partition s such that every substring of the partition is a palindrome.

Return the minimum cuts needed for a palindrome partitioning of s.

For example, given s = "aab",
Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut.

这题我刚开始做的时候还是用dp求出一个二维回文标志数组,然后从头往后用bfs求跳到结尾的最小步数,可惜超时。看了讨论版才知道可以用dp,

而且代码可以如此的精简。

class Solution {public:    int minCut(string s) {        // Note: The Solution object is instantiated only once and is reused by each test case.        /*  TLE because of bfs        //DP for calculating ispa and bfs for calculating result (TLE Yunk)        int len = s.length();        if(0 == len) return 0;        vector<vector<bool> > ispa(len,vector<bool>(len,false));        //build ispa with DP        for(int i = 1; i <= len; ++i){            for(int j = 0; j + i - 1 < len; ++j){                int k = j + i - 1;                if(1 == i)      ispa[j][j] = true;                else if(2 == i)     ispa[j][k] = (s[j] == s[k]);                else                    ispa[j][k] = (s[j] == s[k] && ispa[j+1][k-1]);            }        }            //calculate min cut        //bfs from back to front        queue<pair<int,int> > que;        que.push(make_pair(len-1,0));        while(!que.empty()){            pair<int,int> p = que.front();            que.pop();            int id = p.first;            int step = p.second;            for(int j = 0; j <= id; ++j){                if(ispa[j][id]){                    if(j == 0){//can get final point                        return step;                    }                    que.push(make_pair(j-1,step+1));                }            }        }        return -1;        */                //use dp to calculate mincut        //dp[i] = min{ dp[j+1]+1 | j >= i && ispa[i][j] == true}         //from back to front ,result is dp[0] - 1        int len = s.length();        if(0 == len) return 0;        vector<vector<bool> > ispa(len,vector<bool>(len,false));        vector<int> dp(len+1);        dp[len] = 0;        for(int i = len-1; i >= 0; --i ){            dp[i] = len - i;            for(int j = i ; j < len; ++j){                if(s[i] == s[j] && (j - i < 2 || ispa[i+1][j-1])){                    ispa[i][j] = true;                    dp[i] = min(dp[i], dp[j+1] + 1 );                }            }        }        return dp[0]-1;            }};


原创粉丝点击