5. 最长回文子串

题目

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

示例 1:

输入:s = "babad"

输出:"bab"

解释:"aba" 同样是符合题意的答案。

示例 2:

输入:s = "cbbd"

输出:"bb"

提示:

  • 1 <= s.length <= 1000
  • s 仅由数字和英文字母组成

代码

完整代码

c 复制代码
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

bool isHuiwen(char* head, char* tail)
{
    while (head < tail)
    {
        if((*head) != (*tail))
        {
            return false;
        }
        head++;
        tail--;
    }
    return true;
}

char* longestPalindrome(char* s) {
    int len = strlen(s);
    if(len == 1)
    {
        return s;
    }
    char* head = s,*tail = s + (len - 1);
    char* res = (char*)calloc(len + 1, sizeof(char));
    while(head < s + len - 1)
    {
        while(head != tail)
        {
            if(isHuiwen(head, tail))
            {
                if(tail-head+1 > strlen(res))
                {
                    strncpy(res, head, tail-head+1);
                }
            }
            tail--;
        }
        tail = s + (len - 1);
        head++;
    }
    if(strlen(res) == 0)
    {
        strncpy(res, s, 1);
    }
    return res;
}

// int main(void)
// {
//     char a[] = "bb";
//     printf("return %s",longestPalindrome(a));
// }

思路分析

  1. 检查回文 :定义一个函数 isHuiwen 来检查字符串 s 的子串是否为回文。
  2. 遍历字符串 :使用两个指针 headtail 来遍历字符串的所有子串。
  3. 记录最长回文子串:每次找到一个回文子串时,比较其长度并记录最长的那个。

拆解分析

  • 检查回文:通过两个指针从字符串的两端向中间移动,检查字符是否相同。
  • 遍历字符串:从字符串的每一个起点开始,检查从当前起点到终点的所有子串。
  • 记录结果:每次发现新的回文子串,如果其长度大于当前记录的最长回文子串的长度,则更新结果。

复杂度分析

  • 时间复杂度O(n^3),其中 n 是字符串的长度。遍历所有子串需要 O(n^2),每次检查回文需要 O(n)
  • 空间复杂度O(n),需要额外的空间来存储最长回文子串。

结果

O(n^3)恐怖如斯

一题多解

动态规划

动态规划思路分析

  1. 定义状态 :使用二维数组 dp,其中 dp[i][j] 表示子串 s[i...j] 是否为回文。
  2. 状态转移 :如果 s[i] == s[j]dp[i+1][j-1] 为真,则 dp[i][j] 为真。
  3. 初始化 :所有单个字符都是回文,即 dp[i][i] = true
  4. 结果更新:在遍历过程中记录最长的回文子串。

动态规划复杂度分析

  • 时间复杂度O(n^2),遍历所有子串。
  • 空间复杂度O(n^2),使用二维数组存储结果。

动态规划代码

c 复制代码
char* longestPalindrome(char* s) {
    int len = strlen(s);
    if (len < 2) {
        return s;
    }

    int maxLen = 1, start = 0;
    bool dp[1000][1000] = {false};

    for (int i = 0; i < len; i++) {
        dp[i][i] = true;
    }

    for (int j = 1; j < len; j++) {
        for (int i = 0; i < j; i++) {
            if (s[i] == s[j]) {
                if (j - i == 1) {
                    dp[i][j] = true;
                } else {
                    dp[i][j] = dp[i + 1][j - 1];
                }
            } else {
                dp[i][j] = false;
            }

            if (dp[i][j] && j - i + 1 > maxLen) {
                maxLen = j - i + 1;
                start = i;
            }
        }
    }

    char* res = (char*)malloc((maxLen + 1) * sizeof(char));
    strncpy(res, &s[start], maxLen);
    res[maxLen] = '\0';
    return res;
}

结果

中心扩展法

中心扩展法思路分析

  1. 中心扩展:从字符串的每个字符和每两个字符之间作为中心,向两边扩展寻找回文子串。
  2. 记录结果:在扩展过程中记录最长的回文子串。

中心扩展法复杂度分析

  • 时间复杂度O(n^2),每个字符都需要进行扩展。
  • 空间复杂度O(1),只使用常数级别的额外空间。

中心扩展法代码

c 复制代码
char* longestPalindrome(char* s) {
    int len = strlen(s);
    if (len < 2) {
        return s;
    }

    int maxLen = 1, start = 0;
    
    for (int i = 0; i < len; i++) {
        int l = i, r = i;
        while (l >= 0 && r < len && s[l] == s[r]) {
            if (r - l + 1 > maxLen) {
                maxLen = r - l + 1;
                start = l;
            }
            l--;
            r++;
        }

        l = i, r = i + 1;
        while (l >= 0 && r < len && s[l] == s[r]) {
            if (r - l + 1 > maxLen) {
                maxLen = r - l + 1;
                start = l;
            }
            l--;
            r++;
        }
    }

    char* res = (char*)malloc((maxLen + 1) * sizeof(char));
    strncpy(res, &s[start], maxLen);
    res[maxLen] = '\0';
    return res;
}

结果

相关推荐
技术蔡蔡14 分钟前
Android字节码处理-函数耗时统计揭秘
算法·面试
qing_04060322 分钟前
数据结构——二叉搜索树
数据结构·c++·二叉树·二叉搜索树
Felven36 分钟前
B. Skibidus and Ohio
算法
yonuyeung41 分钟前
代码随想录算法【Day54】
java·数据结构·算法
敲上瘾1 小时前
基础dp——动态规划
java·数据结构·c++·python·算法·线性回归·动态规划
西猫雷婶1 小时前
python学智能算法(三)|模拟退火算法:深层分析
算法·机器学习·模拟退火算法
张有志_1 小时前
STL容器终极解剖:C++ vector源码级实现指南 | 从内存分配到异常安全的全流程避坑
c语言·c++·算法·开源·visual studio
mvufi2 小时前
day58 第十一章:图论part08
数据结构·算法·图论
醉城夜风~2 小时前
[数据结构]栈详解
数据结构
williamzhou_20132 小时前
深搜专题2:组合问题
数据结构·算法