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

5.最长回文子串

时间:2023-03-11 21:47:28浏览次数:52  
标签:子串 最长 longest && first find 回文

最长回文子串

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

如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。

示例 1:

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

输入:s = "cbbd"
输出:"bb"

提示:

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

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/longest-palindromic-substring
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路1:动态规划

见注释。

code

class Solution {
public:
    //朴素写法:遍历每一个子串并判断是否为回文串

    //o(n^2)遍历以及O(n)的判断时间复杂度
    //一种是优化O(n ^ 2),尝试用双指针
    //双指针or滑动窗口:同一端出发,遇到不是回文串就退出?显然不行
    //从数组两端出发,也不行,向那边移动呢?
    //一种是优化回文子串的判断
    //优化回文子串的判断时间:利用已有的回文子串的信息进行辅助判断
    //"aba" -> "xabax" or "xabay"
    
    //动态规划来利用已有的信息辅助判断回文子串
    //状态表示:f[i,j]子串[i,j]是否为回文串
    //状态转移:f[i,j] = f[i+1,j-1] && (s[i] == s[j])
    //初始化:单个字符必然是回文串 && 两个字符的也要单独判断
    //遍历顺序:先初始化f[i+1,j-1],会先使用i+1的值,因此i要倒序遍历,j可以顺序遍历

    string longestPalindrome(string s) {
        
        int n = s.size();
        vector<vector<int>> f(n,vector<int>(n,0));

        for(int i = 0;i < n;i ++) f[i][i] = 1;

        for(int i = n-1;i >= 0;i --)
        {
            for(int j = i + 1;j < n;j ++)
            {
                if(j - i == 1 && s[i] == s[j]) f[i][j] = 1;
                else if(f[i+1][j-1] && (s[i] == s[j])) f[i][j] = 1;
            }
        }
        
        pair<int,int> longest = {0,0};
        int i,j;
        for(i = 0;i < n;i ++)
        {
            for(j = i;j < n;j ++)
            {
    
                if(f[i][j] && j - i + 1 >= longest.second - longest.first + 1) longest = {i,j};
                
            }
        }
        
        
        return s.substr(longest.first,longest.second - longest.first + 1);

    }
};

解题思路2:中心扩散法

使用动态规划的空间复杂度是\(O(n^2)\)。接下来尝试对动态规划的时间复杂度进行优化。为了利用原有的回文子串的信息,我们只需要不断向外扩展两个字符串即可,就可以找到当前为中心开始向外扩展的可以到达的最长的字符串,中心可以是单个的字符串也可以是两个相同的字符串。

code

class Solution {
public:
   
    pair<int,int> diffusion(string & s,int i,int j)
    {
        while(i >= 0 && j < s.size())
        {
            if(i - 1 >= 0 && j + 1 < s.size() && s[i-1] == s[j+1]) i --,j++;
            else break;     
        }

        return {i,j};
    }
    string longestPalindrome(string s) {
        
        int n = s.size();
        
        pair<int,int> longest;

        for(int i = 0;i < n;i ++)
        {
            pair<int,int> find;
            find = diffusion(s,i,i);
            if(find.second - find.first + 1 >= longest.second - longest.first + 1) longest = find;
            
            if(i + 1 < n && s[i] == s[i+1]) find = diffusion(s,i,i+1);
            if(find.second - find.first + 1 >= longest.second - longest.first + 1) longest = find;
            

        }

        return s.substr(longest.first,longest.second - longest.first + 1);


    }
};

解题思路3:马拉车算法

标签:子串,最长,longest,&&,first,find,回文
From: https://www.cnblogs.com/huangxk23/p/17207044.html

相关文章

  • 【LeetCode回溯算法#05】分割回文串(复习双指针判断回文以及substr函数使用记录)
    分割回文串力扣题目链接给你一个字符串s,请你将s分割成一些子串,使每个子串都是回文串。返回s所有可能的分割方案。回文串是正着读和反着读都一样的字符串。示例......
  • 回文山
     /***@version1.0*@auther孙沐华*StringBuffer跟StingBuilder字符串内容是存在char[]value,所以在变化(增加/删除)*中不用每次都更换地址(即不是每次都......
  • 272. 最长公共上升子序列
    题目来源acwing题目难度3星算法标签dp+优化参考程序#include<iostream>usingnamespacestd;constintN=3005;intn;inta[N],b[N];//dp[i][j]表......
  • 无重复字符最长子串
    给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。 示例 1:输入:s="abcabcbb"输出:3解释:因为无重复字符的最长子串是"abc",所以其长度......
  • P4551 最长异或路径
    给定一棵nn个点的带权树,结点下标从11开始到nn。寻找树中找两个结点,求最长的异或路径。异或路径指的是指两个结点之间唯一路径上的所有边权的异或。 处理出每个点......
  • 4.无重复字符的最长子串
    3.无重复字符的最长子串classSolution{public:intlengthOfLongestSubstring(strings){unordered_map<char,int>map;intans=0;......
  • 统计文本文件的最长子串的长度
    publicclasstest_a{publicstaticvoidmain(String[]args)throwsIOException{Stringpath="F:/piao.txt";FileInputStreamfis=new......
  • 计算最长英语单词链
    课堂练习题目:计算最长英语单词链。一、题目内容:大家经常玩成语接龙游戏,我们试一试英语的接龙吧:一个文本文件中有N个不同的英语单词,我们能否写一个程序,快速找出最长的......
  • 计算英语文本中首尾接龙最长数量
    publicclassTest1{publicstaticvoidmain(String[]args)throwsIOException{//TODO自动生成的方法存根Stringfilename="E:\\123......
  • P2679 [NOIP2015 提高组] 子串
    两个仅包含小写英文字母的字符串AA和BB。现在要从字符串AA中取出kk个互不重叠的非空子串,然后把这kk个子串按照其在字符串AA中出现的顺序依次连接起来得到一个......