题解 | #密码截取#

密码截取

http://www.nowcoder.com/practice/3cd4621963e8454594f00199f4536bb1

题目链接https://www.nowcoder.com/practice/3cd4621963e8454594f00199f4536bb1?tpId=37&&tqId=21255&rp=1&ru=/exam/oj/ta&qru=/exam/oj/ta&sourceUrl=%2Fexam%2Foj%2Fta%3FtpId%3D37

题目描述

求一个串的最长回文子串?

方法一:中心对称向外扩展

  • 不难发现,回文串只存在两种形式:
    • 1.AA型:即由偶数个字符组成的回文串
    • 2.ABA型:即由奇数个字符组成的回文串
    所以我们只需遍历每一个数时判断以当前数为中心向外扩展构成的AA型ABA型回文串的最大长度即可算法执行过程如图(以样例12HHHHA举例): i表示当前遍历的元素,假设某一时刻i遍历到途中元素时
  • 先计算能扩展的最长AA型的长度,扩展方式即以i为中心,分别向i的左右向外直至碰到左右两边出现不相等的情况。 alt
  • 再计算能扩展的最长ABA型的长度,扩展方式即以i和i + 1为中心,分别向i与i + 1的左右向外直至碰到左右两边出现不相等的情况。注意:ABA型只有i和i + 1代表的元素相等才可能构成回文串,否则不必扩展。 alt
  • 按这种方式计算,每个元素为中心的两种回文情况都能考虑到,故一定能求得最终解。

时间复杂度:需要遍历一遍数组,然后对每个元素执行两次向外扩展,故为O(n²)

空间复杂度:O(1)

参考代码

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 3e3 + 10;

int main()
{
   string a;
   cin >> a;
   int ans = 1;
   /*遍历每一个元素*/
   for (int i = 0; i < a.size(); i ++ ) {
       /*扩展计算最长AA型的回文串*/
   	int l = i - 1, r = i + 1;
   	while (l >= 0 && r < a.size() && a[l] == a[r]) {
   		ans = max(ans, r - l + 1);    //更新答案
   		l -- , r ++ ;
   	}
       /*扩展计算最长ABA型的回文串*/
   	l = i, r = i + 1;
   	while (l >= 0 && r < a.size() && a[l] == a[r]) {
   		ans = max(ans, r - l + 1);    //更新答案
   		l -- , r ++ ;
   	}
   }	
   cout << ans << "\n";
   return 0;
}

方法二:动态规划

dp[j][i]表示索引j到索引i的子串是否是回文串,可以发现有如下三种情况可以转移:

  • 1.i == j: 此时只有一个元素,是回文串,故dp[i][j] = true;
  • 2.i - j = 1 && str[i] == str[j]: 此时回文,dp[i][j] = true;
  • 3.i - j > 1 && str[i] == str[j] && dp[i - 1][j + 1]: dp[i][j] = true;

代码如下

#include <iostream>
#include <string>
#include <vector>
using namespace std;
const int N = 3e3 + 10;
int dp[N][N];

int main(){
    string s;
    cin >> s;
    int n = s.size();
    int maxn = 1;       //最长回文子串的长度初始化为1
    for (int i = 0; i < n; i++ )
        for (int j = 0; j <= i; j++ )
        {
            /*状态转移*/
            if(i == j) dp[j][i] = 1;
            else if (i-j == 1) dp[j][i] = (s[i]==s[j]);
            else dp[j][i] = ( s[j] == s[i] && dp[j+1][i-1] );
            if(dp[j][i] && maxn < i - j + 1) maxn = i - j + 1;  //更新答案
        }
    cout << maxn << endl;
    return 0;
}

时间复杂度: O(n²)

空间复杂度: O(n²)

全部评论
方法一的中心扩展法里,AA和ABA型说反了吧。AA型是i与i+1相等,再依次扩展;ABA型才是有一个中心i,i-1与i+1相等后,再依次扩展。
点赞 回复 分享
发布于 2023-01-12 17:30 四川

相关推荐

但听说转正率很低,我现在有在实习了,好纠结要不要去
熬夜脱发码农:转正率低归低,但是实习的经历你可以拿着,又不是说秋招不准备了
点赞 评论 收藏
分享
看到这个内容真是闹麻了。。。。。。现在有了AI以后很多人面试都会作弊吗?&nbsp;那对老老实实面试的人岂不是不公平....
程序员牛肉:公平那是对小孩子讲的童话故事,成年人的世界只有能不能接受失败的后果。 你要是能接受面试作弊被发现之后多家公司联合永久拉黑的后果,你就搞。
你找工作的时候用AI吗?
点赞 评论 收藏
分享
06-17 00:26
门头沟学院 Java
程序员小白条:建议换下项目,智能 AI 旅游推荐平台:https://github.com/luoye6/vue3_tourism_frontend 智能 AI 校园二手交易平台:https://github.com/luoye6/vue3_trade_frontend GPT 智能图书馆:https://github.com/luoye6/Vue_BookManageSystem 选项目要选自己能掌握的,然后最好能自己拓展的,分布式这种尽量别去写,不然你只能背八股文了,另外实习的话要多投,尤其是学历不利的情况下,多找几段实习,最好公司title大一点的
无实习如何秋招上岸
点赞 评论 收藏
分享
评论
11
4
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务