• 炒一下冷饭---回文子串问题


    好久没刷题了,为了准备秋招,面了几家公司提前感受面试氛围,一直在背八股文~

    后面不打算再面了,还是要回归基础~

    今天炒个冷饭,看一下回文子串的问题,奇怪的是leetcode这个题我竟然没有写过 0 . 0

    题目短的可怜,证明它真的简单的很多人不屑去做。。

    思路:

    一、中心扩展法,直接上代码,没有什么好解释的 

    1. class Solution {
    2. public:
    3. string longestPalindrome(string s) {
    4. int n=s.size();string s1,s2;
    5. int result=INT_MIN;
    6. if(n==0||n==1)return s;
    7. for(int index=0;index<n;index++)
    8. {
    9. int left=index;
    10. int right=index;
    11. int num1=1;
    12. while(left>=0&&right<n){
    13. if(s[left]==s[right])
    14. {
    15. if(left!=right)num1+=2;
    16. if(num1>=s1.size())s1=s.substr(left,num1);
    17. }
    18. else break;
    19. left--;
    20. right++;
    21. }
    22. }
    23. for(int index=0;index<n;index++)
    24. {
    25. int indey=index+1;
    26. int index_1=index;
    27. int index_2=indey;
    28. int num2=0;
    29. while(index_1>=0&&index_2<n&&s[index_1]==s[index_2]){
    30. num2+=2;
    31. if(num2>=s2.size())s2=s.substr(index_1,num2);
    32. index_1--;index_2++;
    33. }
    34. }
    35. return s1.size()>s2.size()?s1:s2;
    36. }
    37. };

    二、动态规划

    动规适合解决无数重复的子问题,它的思想其实就是递归。

    回文串的重复子问题是什么呢?

            如果一个字符串 s 是 回文串,那么 它去掉首尾肯定也是回文串【s.size()>2】,如下所示:

     所以,重复子问题,就是去判断 子串是否是回文串。

    动规五部曲:

    1.dp[i][j]含义:表示 s 下标 从 i  到  j  是否为回文串;

    2.初始化:每一个字符都是一个回文子串

    3.递推公式:考虑边界条件:如果字符串长度为 2、3,只要保证 s[i]==s[j]就可判断 它是回文

    4.遍历:从前往后

    5.打印dp

    代码:

    1. class Solution {
    2. public:
    3. string longestPalindrome(string s) {
    4. if(s.size()==1)return s;
    5. int begin=0;
    6. int maxlen=1;
    7. vector<vector<int>>dp(s.size(),vector<int>(s.size()));
    8. //dp 表示 s 从 i 到 j 是否为回文子串;
    9. for(int i=0;i<s.size();i++)dp[i][i]=1;//初始化,本身肯定是回文串
    10. for(int length=2;length<=s.size();length++)
    11. {
    12. for(int leftindex=0;leftindex<s.size();leftindex++)
    13. {
    14. int rightindex=length+leftindex-1;
    15. if(rightindex>=s.size())break;//如果右边界越界了就跳出
    16. //如果 左右边界值不等 显然不能为回文串
    17. if(s[leftindex]!=s[rightindex])dp[leftindex][rightindex]=0;
    18. else{// 奇数 AbA保证左右相等就行 偶数 AA 保证 左右相等就行
    19. if(rightindex-leftindex<=2)dp[leftindex][rightindex]=1;
    20. else{//如果字符串长度>3,递归判断前面一个子串是否是回文串
    21. dp[leftindex][rightindex]=dp[leftindex+1][rightindex-1];
    22. }
    23. }
    24. //找到了一个回文串就更新一次 begin 与 maxlen
    25. if(dp[leftindex][rightindex]&&rightindex-leftindex+1>maxlen){
    26. maxlen=rightindex-leftindex+1;
    27. begin=leftindex;
    28. }
    29. }
    30. }
    31. return s.substr(begin,maxlen);
    32. }
    33. };

     遍历不太符合正常的动规方法,个人感觉不如 中心扩展法来的实在,毕竟空间复杂度都是O(n^2)

  • 相关阅读:
    LaTeX中的数学符号
    22.括号生成
    DAY 66 数据库缓存服务——NoSQL之Redis配置与优化
    BaseException 工具类
    conda创建环境、安装包到环境迁移
    uboot源码
    springsecurity+oauth 分布式认证授权笔记总结12
    Vue_指令
    Spring Security 为用户示例添加角色
    总结:Prometheus之PromQL操作符
  • 原文地址:https://blog.csdn.net/qq_57328462/article/details/125602175