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 就行,最后再做截取操作。

  • 相关阅读:
    使用log4j在javaweb中实现日志管理
    android 开发:使用SwipeRefreshLayout实现下拉刷新
    android 开发:保存图片到SD卡上
    android 开发:网页爬虫获取腾讯财经滚动新闻
    android 开发:Json的发送和接收
    安卓学习笔记之新浪微博开发(一)
    android之webview使用
    Android 使WebView支持HTML5 Video(全屏)播放的方法
    委托
    八月的第一场雨
  • 原文地址:https://www.cnblogs.com/wangxf2019/p/14688312.html
Copyright © 2011-2022 走看看