面试题29:回文字符串

回文的题经常出现在算法题中,下面总结了leetcode出现的6个关于回文的题目。

  1. 如何判断字符串是回文字符串?(easy)
  2. 如何判断一个整数是回文的?(easy)
  3. 如何用最少的切法将一个字符串切成几个回文串组成?(dp)
  4. 寻找一个字符串中最长的回文串?(马拉车算法)
  5. 如何通过在字符串的头部添加最少的字符,使得添加后的字符串成为回文字符串?(kmp中最长前缀后缀数组)
  6. 将字符串划分为回文串,返回所有可能的结果?(dfs)

1.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.

 1 class Solution {
 2 public:
 3     bool isAlphanumberic(char c){
 4         if((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c<='9')) return true;
 5         else return false;
 6     }
 7     bool isPalindrome(string s) {
 8         int n = s.length();
 9         int left = 0;
10         int right = n - 1;
11         while(left < right){
12             if(!isAlphanumberic(s[left])){
13                 left++;
14                 continue;
15             }
16 
17             if(!isAlphanumberic(s[right])){
18                 right--;
19                 continue;
20             }
21             if(s[left] == s[right] || abs(s[left] - s[right]) == 32){
22                 left++;
23                 right--;
24             }else{
25                 return false;
26             }
27         }
28         return true;
29     }
30 };

2.

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

click to show spoilers.

 1 class Solution {
 2 public:
 3     bool isPalindrome(int x) {
 4         if(x < 0) return false;
 5         int len = 1;
 6         while(x / len >= 10){
 7             len *= 10;
 8         }
 9 
10         while(x > 0){
11             int left = x / len;
12             int right = x % 10;
13             if(left != right){
14                 return false;
15             }else{
16                 x = x % len / 10;
17                 len /= 100;
18             }
19         }
20         return true;
21     }
22 };

3.

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",
Return1since the palindrome partitioning["aa","b"]could be produced using 1 cut.

 1 class Solution {
 2 public:
 3     bool isPalindrome(string s) {
 4         int n = s.length();
 5         if (n < 2)
 6             return true;
 7         int left = 0;
 8         int right = n - 1;
 9         while (left < right) {
10             if (s[left] == s[right]) {
11                 left++;
12                 right--;
13             } else {
14                 return false;
15             }
16         }
17         return true;
18     }
19     int minCut(string s) {
20         int n = s.length();
21 
22         vector<int> dp(n,n-1);
23         for (int i = 1; i <= n; i++) {
24             if (isPalindrome(s.substr(0, i)))
25                 dp[i-1] = 0;
26             else {
27                 for (int j = 1; j < i; j++) {
28                     if (isPalindrome(s.substr(j, i - j))) {
29                         dp[i-1] = min(dp[i-1],dp[j-1] + 1);
30                     }
31                 }
32             }
33 
34         }
35         return dp[n-1];
36     }
37 };

4.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.

 1 class Solution {
 2 public:
 3     string longestPalindrome(string s) {
 4         string t = "$#";
 5         for (size_t i = 0; i < s.length(); i++) {
 6             t += s[i];
 7             t += "#";
 8         }
 9 
10         int mx = 0;
11         int id = 0;
12         int n = t.size();
13         vector<int> dp(n, 0);
14         int resCenter = 0, resLen = 0;
15         for (int i = 1; i < n; i++) {
16             dp[i] =  mx > i ? min(mx - i, dp[2 * id - i]) : 1;
17             while (t[i + dp[i]] == t[i - dp[i]])
18                 dp[i]++;
19             if (mx < dp[i]+i) {
20                 mx = dp[i]+i;
21                 id = i;
22             }
23             if (dp[i] > resLen) {
24                 resLen = dp[i];
25                 resCenter = i;
26             }
27         }
28         return s.substr((resCenter - resLen) / 2, resLen - 1);
29     }
30 };

5.Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. Find and return the shortest palindrome you can find by performing this transformation.

For example:

Given "aacecaaa", return "aaacecaaa".

Given "abcd", return "dcbabcd".

Credits:
Special thanks to @ifanchu for adding this problem and creating all test cases. Thanks to @Freezen for additional test cases.

class Solution {
public:
    string shortestPalindrome(string s) {
        string r = s;
        reverse(r.begin(), r.end());
        string t = s + "#" + r;
        vector<int> next(t.size(), 0);
        for (int i = 1; i < t.size(); ++i) {
            int j = next[i - 1];
            while (j > 0 && t[i] != t[j]) j = next[j - 1];
            next[i] = (j += t[i] == t[j]);
        }
        return r.substr(0, s.size() - next.back()) + s;
    }
};

6.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"]
  ]
 1 class Solution {
 2 public:
 3     bool isPalindrome(string &s) {
 4         int n = s.length();
 5         if (n == 1) return true;
 6         int left = 0;
 7         int right = n - 1;
 8         while (left < right) {
 9             if (s[left] == s[right]) {
10                 left++;
11                 right--;
12             } else {
13                 return false;
14             }
15         }
16         return true;
17     }
18     vector<vector<string>> partition(string s) {
19         vector<vector<string>> res;
20         if (s.empty()) return res;
21         int n = s.length();
22         for (int i = 1; i <= n; i++) {
23             string substr = s.substr(0, i);
24             if (isPalindrome(substr)) {
25                 vector<vector<string>> tmp = partition(s.substr(i));
26                 if (tmp.empty()) {
27                     vector<string> v;
28                     v.push_back(substr);
29                     res.push_back(v);
30                 } else {
31                     for (size_t j = 0; j < tmp.size(); j++) {
32                         tmp[j].insert(tmp[j].begin(), substr);
33                         res.push_back(tmp[j]);
34                     }
35                 }
36             }
37         }
38         return res;
39     }
40 };
原文地址:https://www.cnblogs.com/wxquare/p/6881832.html