求一个字符串中的最长回文序列

如题,下面说说我的思路,

我想到的算法如下:

a. 遍历字符串,找到所有相邻两个字母相同的位置(比如aa),加入到链表centers1中,找到所有隔一个字符相同的位置(比如aba),加入到centers2中,复杂度O(N);

b. 设置最大回文的长度maxLength=2和回文的起始位置start=centers1[0];

c. 遍历centers1,对每一个位置进行如下操作:

    设置head和tail两个int变量,表示前后到达字符的位置,head=i-1,tail=i+2;

    判断head与tail位置上的字符是否相同,相同则head--、tail++,不同则比较tail-head-1与maxLength的大小,最大值为新的maxLength,start为原值或者head+1;

d. 遍历centers2,对每一个位置进行如下操作:

    设置head和tail两个int变量,表示前后到达字符的位置,head=i-1,tail=i+3;

    判断head与tail位置上的字符是否相同,相同则head--、tail++,不同则比较tail-head-1与maxLength的大小,最大值为新的maxLength,start为原值或者head+1;

e. 结束对两个数组的遍历后,maxLength即为最大的回文长度,start为回文的起始位置。


分析:

步骤c和d的时间复杂度比较不好算,最简单的情况下,没有相同的相邻相同或者隔一个字符相同的情况,那c和d都不需要时间;最差情况下,所有的字符都相同(aaaaaa),或者字符串是间隔相同的(abababa,这种情况的时间复杂度略好与aaaaaa),那么c和d的复杂度就是0+1+2+...+N/2+...+2+1+0=O(N^2)。平均复杂度不知道该怎么算,因为字符串的平均布局不好处理,你有什么想法吗?


欢迎大家踊跃讨论和拍砖!!

在Java中,我们可以使用动态规划的方法来寻找一个字符串中的最长回文子串。回文是一个正读和反读都一样的字符序列,例如"madam"、"racecar"等。下面是一个简单的步骤: 1. 首先,创建一个长度与输入字符串相同的布尔数组`dp`,其中`dp[i][j]`表示从索引`i`到`j`的子串是否为回文。 2. 初始化边界条件:如果两个索引相等,则该子串只包含一个字符,自然是回文;如果只有一个字符则是回文;对于其他情况,如果第一个字符与最后一个字符不相等,则不是回文。 3. 使用两层循环遍历数组,检查每个子串的首尾字符是否相等,如果相等则继续检查中间部分(即去掉首尾字符后的子串),如果这个中间部分也是回文,则当前子串就是回文。 4. 在遍历过程中,记录下最长回文子串的起始位置和结束位置,最后可以根据这两个位置获取最长回文串。 下面是示例代码片段: ```java public String longestPalindrome(String s) { int n = s.length(); boolean dp[][] = new boolean[n][n]; int start = 0, maxLen = 1; for (int i = 0; i < n; ++i) { dp[i][i] = true; } // 检查长度为2的子串 for (int i = 0; i < n - 1; ++i) { if (s.charAt(i) == s.charAt(i + 1)) { dp[i][i + 1] = true; start = i; maxLen = 2; } } // 检查长度大于2的子串 for (int k = 3; k <= n; ++k) { for (int i = 0; i < n - k + 1; ++i) { int j = i + k - 1; if (s.charAt(i) == s.charAt(j) && dp[i + 1][j - 1]) { dp[i][j] = true; if (k > maxLen) { start = i; maxLen = k; } } } } return s.substring(start, start + maxLen); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值