博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
5. Longest Palindromic Substring (DP)
阅读量:4591 次
发布时间:2019-06-09

本文共 3041 字,大约阅读时间需要 10 分钟。

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 = 1;    int pStart = 0;    bool flag[n][n];    for(int i = 0; i < n; i++){        flag[i][i] = true;        for(int j = i+1; j < n; j++){            flag[i][j] = false;        }    }        for(int j = 1; j < n; j++){ //when iterate j, we should already iterated j-1, 可以理解成j之前已排序好=>用插入排序的顺序遍历        for(int i = 0; i < j; i++){             if(s[i]==s[j]){                flag[i][j] = (j==i+1)?true:flag[i+1][j-1];                              if(flag[i][j] && j-i+1 > max){                                        max = j-i+1;                    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指向它右侧位置。
字符串查找——扩展的KMP问题
现在我们要处理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 == 0) return "^$";    char* ret = malloc(sizeof(char)*(n*2+4));    char* pRet = ret;    *pRet++ = '^'; //开始符^    for (int i = 0; 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 = 0, R = 0;    char* ret;    for (int i = 1; i < n-1; i++) {      int i_mirror = 2*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] = 0;            //else: Attempt to expand palindrome centered at i      while (T[i + 1 + P[i]] == T[i - 1 - 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 = 0;    int centerIndex = 0;    for (int i = 1; i < n-1; i++) {      if (P[i] > maxLen) {        maxLen = P[i];        centerIndex = i;      }    }        ret = malloc(sizeof(char)*maxLen+1);    strncpy(ret, s+(centerIndex - 1 - maxLen)/2, maxLen);    ret[maxLen] = '\0';    return ret;  }

 

转载于:https://www.cnblogs.com/qionglouyuyu/p/5359597.html

你可能感兴趣的文章
magento开发手册之目录结构
查看>>
换个红圈1微信头像恶搞一下好友
查看>>
javascript学习_廖大_20170218
查看>>
bzoj2038: [2009国家集训队]小Z的袜子(hose) 莫队
查看>>
火车头采集基本使用
查看>>
MYSQL中插入数据以及修改数据的部分方法
查看>>
unity中遍历动画得到动画名字和动画数量
查看>>
调整WebLogic的时间
查看>>
Linux学习笔记总结--配置iptables防火墙
查看>>
win10 安装mysql
查看>>
SQL文 Update From 写法
查看>>
pyc文件的本质
查看>>
洛谷 - P2602 - 数字计数 - 数位dp
查看>>
android 环境配置 与 运行错误
查看>>
POJ 2653
查看>>
余承东:未来5年中国大部分智能手机厂商消失
查看>>
Android中个人推崇的数据库使用方式
查看>>
关于H.264 x264 h264 AVC1
查看>>
北戴河之旅
查看>>
search for a range(找出一个数在数组中开始和结束位置)
查看>>