其他分享
首页 > 其他分享> > leetcode5. 最长回文子串

leetcode5. 最长回文子串

作者:互联网

leetcode5. 最长回文子串

1. 题目

给你一个字符串 s,找到 s 中最长的回文子串。

示例 1:
输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。

示例 2:
输入:s = “cbbd”
输出:“bb”

示例 3:
输入:s = “a”
输出:“a”

示例 4:
输入:s = “ac”
输出:“a”

2. 解答

回文串:如果一个字符串正着读和反着读都是一样的,就是回文串

中心扩展算法:
我们观察到回文中心的两侧互为镜像。因此,回文可以从它的中心展开,并且只有2n-1个这样的中心。
你可能会问,为什么会是 2n - 1 个,而不是 n 个中心?
因为回文的中心要区分单双。

对于 n 长度的字符串,我们其实不知道它的回文串中心倒底是单数还是双数,所以我们要对这两种情况都做遍历,也就是 n+(n-1) = 2n - 1,所以时间复杂度为 O(n)。

当中心确定后,我们要围绕这个中心来扩展回文,那么最长的回文可能是整个字符串,所以时间复杂度为 O(n)。

所以总时间复杂度为 O(n^2)

// 中心扩展法

#define MAX(a, b) (((a) > (b)) ? (a) :(b))

int expandAroundCenter(char *s, int len, int left, int right) {
    int l = left;
    int r = right;
    while (l >= 0 && r < len && s[l] == s[r]) {
        // 计算以left和right为中心的回文串长度
        l--;
        r++;
    }
    return r - l - 1;
}

char * longestPalindrome(char * s) {
    int len = strlen(s);
    if (len <= 1) {
        return s;
    }

    int start = 0;
    int end = 0;
    int maxLen = 0;
    

    for (int i = 0; i < len; i++) {
        int len1 = expandAroundCenter(s, len, i, i);    // 一个元素为中心
        int len2 = expandAroundCenter(s, len, i, i + 1);   // 两个元素为中心
        maxLen = MAX(MAX(len1, len2), maxLen);
        if (maxLen > end - start + 1) {
            start = i - (maxLen - 1) / 2;   // 获取回文串起始点位置
            end = i + maxLen / 2;    // 获取回文串结束点位置        
}
    }
    int index = 0;
    char *res = (char *)malloc(sizeof(char) * (maxLen + 1));
    for (int i = start; i < start + maxLen; i++) {
        res[index++] = s[i];
    }
    res[index] = '\0';
    return res;
}

标签:子串,leetcode5,中心,int,len,char,maxLen,回文
来源: https://blog.csdn.net/yu1500772557/article/details/120187995