zoukankan      html  css  js  c++  java
  • 微软面试题: LeetCode 5. 最长回文子串 出现次数:1

    方法一     中心扩散法

    解析: 回文串一定是 中心对称的,回文串的对称中心可能是 1 个字符,也可能是 2个字符,遍历 s 中的 字符

    分别以 s[i] 和s[i] 、s[i+1]  为中心像两边扩散,记录 最长 回文串的 起始位置 和长度。

    时间 O(n ^ 2)  空间 O(1)

    代码: 

     1 //方法一: 中心扩散法       时间 O(n ^ 2)  空间:O(1)    
     2     string CentralDiffusion(string s)
     3     {
     4         int sub_len = 1;
     5         int start = 0;
     6        
     7         for(int i = 0; i < s.size();++i)
     8         {
     9             int l,r,sub_len_tmp;
    10             //考虑以(s[i],s[i+1])为回文串中心的情况 
    11             if(i + 1 < s.size() && s[i] == s[i+1])
    12             {
    13                 l = i;
    14                 r = i + 1;
    15                 sub_len_tmp = 0;
    16                 while(l >= 0 && r < s.size() && s[l] == s[r])
    17                 {
    18                     sub_len_tmp += 2;
    19                     --l;
    20                     ++r;
    21                 }
    22                 if(sub_len_tmp > sub_len)
    23                 {
    24                     start = l + 1;
    25                     sub_len = sub_len_tmp;
    26                 }
    27             }
    28             //考虑以s[i]为奇数回文串中心的情况 
    29             l = i - 1;
    30             r = i + 1;
    31             sub_len_tmp = 1;
    32             while(l >= 0 && r < s.size() && s[l] == s[r])
    33             {
    34                 sub_len_tmp += 2;
    35                 --l;
    36                 ++r;
    37             }
    38             if(sub_len_tmp > sub_len)
    39             {
    40                 start = l + 1;
    41                 sub_len = sub_len_tmp;
    42             }
    43         }
    44         return s.substr(start,sub_len);
    45     }

    方法二    动态规划

    分析:

    1 个字符 s[i] 的子串一定是回文串,

    2个字符 s[ i : i + 1] 当 s[i] == s[i+1] 时 是回文串,否则不是,

    3 个字符的子串 s[i : i + 2]  : 当 s[i] == s[i+2] 时是回文子串,此时 s[i : i + 2]  内层的 s[i+1:i+1] 只有一个字符,一定是回文的。

    4 个字符 s[i : i+3]  :  当 s[i] == s[i+3] 时是回文子串 而且 其内层 s[i+1:i+2] 也是回文串时, s[i : i+3]  是回文串。

    ........

    1.  定义状态  dp[ i ][ j ]  ,   等于 1    表示 子串 s[ i : j ] 是回文串,等于 0 不是回文串。 0<= j < n, 0 <= i <=j; 

    2.  状态转移方程    dp[ i ][ j ] = dp[ i + 1][ j - 1] == 1 && s[i] == s[j] ?1:0;

    3.  设置初始状态   dp[ i ][ i ] = 1, dp[ i ][ i + 1] =  s[ i ] == s [ i + 1 ] ? 1 : 0;

     1 //方法二: 动态规划   时间 O(n ^ 2)  空间:O(n)    
     2 // dp 的方法虽然时间复杂度也是 O(n ^ 2),但是和中心扩散法相比,避免了很多重复计算,有很好的的性能提升
     3      string dp(string s)
     4      {
     5           const int s_len = s.size();
     6           if(s_len <= 1)
     7           {
     8               return s;
     9           }
    10           int start = 0;
    11           int sub_len = 1;
    12           //定义状态 dp[i][j] , 等于 1 表示s[i:j]是回文子串,等0不是
    13           int dp[s_len][s_len] ;
    14           memset( dp, 0, sizeof(dp));
    15           for(int i = 0; i < s_len; ++i)// dp base case
    16           {
    17               dp[i][i] = 1;
    18               if(i+1 < s_len && s[i] == s[i+1])
    19               {
    20                  dp[i][i+1] = 1;
    21                  start = i;
    22                  sub_len = 2;
    23               }
    24           }
    25           for(int j = 1; j < s_len;++j)
    26           {
    27               for(int i = 0; i < j - 1;++i) //dp[k][k] 和 dp[k][k+1] 作为base case    
    28               {
    29                   if(dp[i+1][j-1] == 1 && s[i] == s[j])//内一层子串是回文的,外层两个字符相同
    30                   {
    31                       if(j - i + 1 > sub_len)
    32                       {
    33                           start = i;
    34                           sub_len = j - i + 1;
    35                       }
    36                       dp[i][j] = 1;//标记 s[i:j] 为回文子串
    37                   }
    38               }
    39           }
    40           return s.substr(start,sub_len);
    41      }

     Tips : 在记录子串信息时,记录 子串的起始位置 start 和 子串长度 sub_len 就行,最后再做截取操作。

  • 相关阅读:
    centos7.6 安装与配置 MongoDB yum方式
    MongoDB 介绍
    centos 关闭selinux
    前端 HTML标签属性
    前端 HTML 标签嵌套规则
    前端 HTML 标签分类
    前端 HTML body标签相关内容 常用标签 表单标签 form里面的 input标签介绍
    前端 HTML body标签相关内容 常用标签 表单标签 form 表单控件分类
    前端 HTML form表单标签 select标签 option 下拉框
    POJ 1426
  • 原文地址:https://www.cnblogs.com/wangxf2019/p/14688312.html
Copyright © 2011-2022 走看看