LeetCode Algorithms 5. Longest Palindromic Substring 题解

来源:互联网 发布:怎么知道ftp端口是多少 编辑:程序博客网 时间:2024/05/14 11:17

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

找出给定字符串的最长回文子串,首先想到使用暴力解法,第一层循环从字符串头遍历到尾,第二层循环从尾部开始到头部,第三层循环检验是否是回文。这样的话时间复杂度很高,不做一些特殊情况的判断就会TLE,以下贴出我的代码:

string Solution::longestPalindrome(string s) {    if (s.length() <= 1) return s;    string res = "";    int front, rear, forward;    int end;    for (int i = 0; i < (int)s.length(); i++) {        forward = 0;        front = i;        end = rear = (int)s.length() - 1;        while (front < rear) {            while (s[front] == s[rear] && front <= rear) {                front++;                rear--;                forward++;             }            /* 找到回文并且回文比最长的回文要长 */            if (front >= rear && end - i + 1 > res.length()) {                res = s.substr(i, end - i + 1);                break;            }            rear = rear + forward - 1;            front = i;            end = rear;            forward = 0;        }        if (res.length() >= s.length() - i) break; // 找到最长的回文就跳出    }    if (res == "") {        return s.substr(0,1);    }    return res;}

很明显,这样做的话会有很多重复操作,浪费了时间,可以使用一个二维数组v[i][j]记录从i个位置到第j个位置的字符串是否是回文,如果是回文,那么去掉子串左右两端后仍然是回文,利用这个概念可以设计出dp转移方程dp[i][j+i-1] = 1 if dp[i+1][j+i-2]==1,然后记录子串头尾位置即可。这样可以把复杂度降到O(n^2)
代码如下:

string Solution::longestPalindrome2(string s) {    if (s.length() <= 1) return s;    vector<vector<int>> dp(s.length(), vector<int>(s.length(), 0)); // dp[i][j]记录从i到j是否为回文    int len = 0;    int start = 0, end = 0;    dp[0][0] = 1;    for (int i = 1; i < (int)s.length(); i++) {        dp[i][i] = 1;        dp[i][i - 1] = 1; // 子串长度为2时,dp[i][i+1]与dp[i+1][i]同状态    }    /* 枚举回文长度 */    for (int subStrLen = 1; subStrLen < s.length(); subStrLen++) {        /* 枚举回文开始位置 */        for (int head = 0; head + subStrLen < s.length(); head++) {            /* 回文去掉左右端字符仍然是回文 */            if (s[head + subStrLen] == s[head] && dp[head + 1][head + subStrLen - 1]) {                dp[head][head + subStrLen] = 1;                if (subStrLen > end - start) {                    start = head;                    end = start + subStrLen;                    break;                }            }        }    }    return s.substr(start, end - start + 1);}
0 0
原创粉丝点击