zoukankan      html  css  js  c++  java
  • [LeetCode] Shortest Palindrome

    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.

    https://leetcode.com/problems/shortest-palindrome/

    其实问题可以转化成求从s[0]开始的最长回文,找到以s[0]开始的最长回文,将剩下的部分倒序补在字符串前面就是答案。在找以s[0]开始的回文的时候,可以从后向前枚举回文结束的字符,在第一个找到的地方退出即可。最坏情况下时间复杂度为O(n^2),用C语言提交AC,704ms。

     1 bool isPalindrom(char* s, int start, int end) {
     2     while (start < end) {
     3         if (s[start] != s[end]) return false;
     4         ++start; --end;
     5     }
     6     return true;
     7 }
     8 
     9 char* shortestPalindrome(char* s) {
    10     int pos = strlen(s) - 1;
    11     for (; pos > 0; --pos) {
    12         if (s[pos] == s[0] && isPalindrom(s, 0, pos)) break;
    13     }
    14     char* res = (char*) malloc(2 * strlen(s) - pos);
    15     int idx = 0;
    16     for (int i = strlen(s) - 1; i > pos; --i) res[idx++] = s[i];
    17     strcpy(res + idx, s);
    18     return res;
    19 }

    但是用C++提交后超时,可能这并不是最佳的答案吧,想到更好的方法后再回来补上代码(已经想到了,见后文)。

     1 class Solution {
     2 public:
     3     bool isPalindrom(string &s, int start, int end) {
     4         while (start < end) {
     5             if (s[start] != s[end]) return false;
     6             ++start; --end;
     7         }
     8         return true;
     9     }
    10     string shortestPalindrome(string s) {
    11         int pos = s.length() - 1;
    12         if (pos == 0) return s;
    13         for (; pos > 0; --pos) {
    14             if (s[pos] == s[0] && isPalindrom(s, 0, pos)) break;
    15         }
    16         string res;
    17         for (int i = s.length() - 1; i > pos; --i) res.push_back(s[i]);
    18         res += s;
    19         return res;
    20     }
    21 };

    求最长回文的Manacher算法时间复杂度为O(n),可以用在这里,但是在判断最长回文的时候需要加一个条件,就是只比较那些以s[0]开始的回文,而根据Manacher算法的特性,id == p[id]时回文一定是从s[0]开始的。所以下面也是用C++写可以AC的代码,因为时间复杂度是O(n),所以只用了16ms。关于Manacher算法,可以看我另一篇文章:

    http://www.cnblogs.com/easonliu/p/4454213.html

     1 class Solution {
     2 public:
     3     int longestPalindrom(string s) {
     4         string s1;
     5         s1.resize(2 * s.length() + 2);
     6         int idx = 0;
     7         s1[idx++] = '$';
     8         s1[idx++] = '#';
     9         for (char a : s) {
    10             s1[idx++] = a;
    11             s1[idx++] = '#';
    12         }
    13         vector<int> p(s1.length(), 0);
    14         int res = 0;
    15         for (int id = 0, i = 1; i < s1.length(); ++i) {
    16             if (i < id + p[id]) p[i] = min(p[2 * id - i], id + p[id] - i);
    17             else p[i] = 1;
    18             while (s1[i + p[i]] == s1[i - p[i]]) ++p[i];
    19             if (id + p[id] < i + p[i]) id = i;
    20             if (p[i] == i) res = max(res, i);
    21         }
    22         return res - 1;
    23     }
    24     
    25     string shortestPalindrome(string s) {
    26         int pos = longestPalindrom(s);
    27         string res;
    28         for (int i = s.length() - 1; i >= pos; --i) res.push_back(s[i]);
    29         return res + s;
    30     }
    31 };
  • 相关阅读:
    Lamp环境搭建
    jquery之下拉列表select
    jquery之radio
    php连接postgresql
    ipython的notebook
    python连接postgresql数据库
    django最简单表单入门
    css制作简单下拉菜单
    下拉列表简单操作
    css制作最简单导航栏
  • 原文地址:https://www.cnblogs.com/easonliu/p/4522724.html
Copyright © 2011-2022 走看看