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.

思路:如果不用动态规划,在两个for循环的情况下,还得依次比较i,j间的每个字符,O(n3)。使用动态规划,O(n2)

char* longestPalindrome(char* s) {
int n = strlen(s);
int max = ;
int pStart = ; bool flag[n][n];
for(int i = ; i < n; i++){
flag[i][i] = true;
for(int j = i+; j < n; j++){
flag[i][j] = false;
}
} for(int j = ; j < n; j++){ //when iterate j, we should already iterated j-1, 可以理解成j之前已排序好=>用插入排序的顺序遍历
for(int i = ; i < j; i++){
if(s[i]==s[j]){
flag[i][j] = (j==i+)?true:flag[i+][j-]; if(flag[i][j] && j-i+ > max){ max = j-i+;
pStart = i;
}
}
}
} s[pStart+max]='\0';
return &s[pStart];
}

方法II:KMP+动态规划,时间复杂度在最好情况下达到O(n)

首先在字符串的每个字符间加上#号。For example: S = “abaaba”, T = “#a#b#a#a#b#a#”。这样所有的回文数都是奇数,以便通过i的对应位置i’获得p[i]
P[i]存储以i为中心的最长回文的长度。For example: 
T = # a # b # a # a # b # a #
P = 0 1 0 3 0 1 6 1 0 3 0 1 0
下面我们说明如何计算P[i]。
假设我们已经处理了C位置(中心位置),它的最长回文数是abcbabcba,L指向它左侧位置,R指向它右侧位置。
现在我们要处理i位置。
if P[ i' ] ≤ R – i,
then P[ i ] ← P[ i' ] 那是因为在L到R范围内,i'的左侧与i的右侧相同,i'的右侧与i的左侧相同,i'左侧与右侧相同 =>i左侧与右侧相同。
else P[ i ] ≥ P[ i' ]. (Which we have to expand past the right edge (R) to find P[ i ].
If the palindrome centered at i does expand past R, we update C to i, (the center of this new palindrome), and extend R to the new palindrome’s right edge.
char* preProcess(char* s) {
int n = strlen(s);
if (n == ) return "^$";
char* ret = malloc(sizeof(char)*(n*+));
char* pRet = ret;
*pRet++ = '^'; //开始符^
for (int i = ; i < n; i++){
*pRet++ = '#';
*pRet++ = s[i];
}
*pRet++ = '#';
*pRet = '$';//结束符$
return ret;
} char* longestPalindrome(char* s) {
char* T = preProcess(s);
int n = strlen(T);
int P[n];
int C = , R = ;
char* ret;
for (int i = ; i < n-; i++) {
int i_mirror = *C-i; // equals to i_mirror = C - (i-C) //if p[i_mirror] < R-i: set p[i] to p[i_mirror]
if(R>i){
if(P[i_mirror] <= R-i){
P[i] = P[i_mirror];
}
else P[i] = R-i;
}
else P[i] = ; //else: Attempt to expand palindrome centered at i
while (T[i + + P[i]] == T[i - - P[i]]) //因为有哨兵^$所以不用担心越界; +1, -1检查下一个元素是否相等,若相等,扩大p[i]
P[i]++; //if the palindrome centered at i does expand past R
if (i + P[i] > R) {
C = i;
R = i + P[i];
}
} // Find the maximum element in P.
int maxLen = ;
int centerIndex = ;
for (int i = ; i < n-; i++) {
if (P[i] > maxLen) {
maxLen = P[i];
centerIndex = i;
}
} ret = malloc(sizeof(char)*maxLen+);
strncpy(ret, s+(centerIndex - - maxLen)/, maxLen);
ret[maxLen] = '\0';
return ret;
}

5. Longest Palindromic Substring (DP)的更多相关文章

  1. leetcode 第五题 Longest Palindromic Substring (java)

    Longest Palindromic Substring Given a string S, find the longest palindromic substring in S. You may ...

  2. Leetcode 之Longest Palindromic Substring(30)

    很经典的一道题,最长回文子串,有多种方法. 首先介绍的一种方法是从中间向两边展开.注意区分aba和abba型的回文串:如果当前最长的子串已经当于两边中最长的子串了,则无需再去判断. //从中间向两边展 ...

  3. LeetCode:5. Longest Palindromic Substring(Medium)

    原题链接:https://leetcode.com/problems/longest-palindromic-substring/description/ 1. 题目要求:找出字符串中的最大回文子串 ...

  4. leetcode:Longest Palindromic Substring(求最大的回文字符串)

    Question:Given a string S, find the longest palindromic substring in S. You may assume that the maxi ...

  5. [LeetCode] Longest Palindromic Substring(manacher algorithm)

    Given a string S, find the longest palindromic substring in S. You may assume that the maximum lengt ...

  6. LeetCode 5 Longest Palindromic Substring(最长子序列)

    题目来源:https://leetcode.com/problems/longest-palindromic-substring/ Given a string S, find the longest ...

  7. LeetCode OJ:Longest Palindromic Substring(最长的回文字串)

    Given a string S, find the longest palindromic substring in S. You may assume that the maximum lengt ...

  8. 21.Longest Palindromic Substring(最长回文子串)

    Level:   Medium 题目描述: Given a string s, find the longest palindromic substring in s. You may assume ...

  9. 5.Longest Palindromic Substring (String; DP, KMP)

    Given a string S, find the longest palindromic substring in S. You may assume that the maximum lengt ...

随机推荐

  1. nginx 服务器 在 centos7 系统下的两种方式

    选用系统 Centos7 < 一 >  使用 yum 安装,该方法比较方便,如果不追求版本推荐使用 01, 添加 nginx 储存库  yum -y install epel-releas ...

  2. ES6 模块导入import 导出export 和module.export

    ES6中新增了模块的导入和导出功能 在实际过程中可以使用 import 和 export 对模块进行导入和导出操作,具体如下 1. 名字导入/导出  (导入名字必须与导出的一致,导入时需要用花括号) ...

  3. 机器学习入门-文本数据-构造Tf-idf词袋模型(词频和逆文档频率) 1.TfidfVectorizer(构造tf-idf词袋模型)

    TF-idf模型:TF表示的是词频:即这个词在一篇文档中出现的频率 idf表示的是逆文档频率, 即log(文档的个数/1+出现该词的文档个数)  可以看出出现该词的文档个数越小,表示这个词越稀有,在这 ...

  4. Python conda 入门

    https://blog.csdn.net/yimingsilence/article/details/79388205 查看版本 conda --version 列出所有的Python环境 cond ...

  5. java输出自身源代码

    如何通过运行程序输出程序源码? 下面是JAVA实现 public class Quine { public static void main(String[] args) { char q = 34; ...

  6. 【358】GitHub 上面文件夹下载方法

    参考:https://www.bilibili.com/read/cv210500/ 参考:https://www.jianshu.com/p/743ecc20ffb2 软件下载:Downloads ...

  7. 转:探讨JS合并两个数组的方法

    我们在项目过程中,有时候会遇到需要将两个数组合并成为一个的情况. 比如: var a = [1,2,3]; var b = [4,5,6]; 有两个数组a.b,需求是将两个数组合并成一个.方法如下: ...

  8. React/anu实现弹出层2

    这次是使用了一个比较罕见的APIReactDOM.unstable_renderSubtreeIntoContainer,ReactDOM.unstable_renderSubtreeIntoCont ...

  9. Todolist功能开发

    一.属性绑定和双向数据绑定: v-bind:title 或简写成 :title实现title属性绑定: v-model实现双向数据绑定(双向是指:当数据变了,input的value会改变:当input ...

  10. 29.Junit测试框架.md

    目录 作用 使用 单个对象的测试 有步骤的测试 注意 作用 用于简化测试,可以对方法,类,包等范围测试 使用 单个对象的测试 在需要测试的方法上加注解@Test,选中方法,运行里选择junit执行 同 ...