每日一道 LeetCode (48):最长回文子串

每天 3 分钟,走上算法的逆袭之路。
前文合集
代码仓库
GitHub: https://github.com/meteor1993/LeetCode
Gitee: https://gitee.com/inwsy/LeetCode
题目:最长回文子串
难度:中等
题目来源:https://leetcode-cn.com/problems/longest-palindromic-substring/
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
示例 2:
输入: "cbbd"
输出: "bb"
解题方案一:暴力解法
暴力方案就很适合我这种脑子不够用的人,首先把字符串中的所有子串取出来,当然哈,取长度大于 1 的子串,不然也没啥意义。
然后挨个判断取出来的子串是否回文串,判断完了以后取到最大的那个,然后返回出来,结束。
public String longestPalindrome(String s) {
int len = s.length();
if (len < 2) {
return s;
}
// 先把字符串转成数组
char[] charArray = s.toCharArray();
// 定义初始位置
int left = 0;
// 定义字符串长度
int length = 1;
// 获取所有子串
for (int i = 0; i < len - 1; i++) {
for (int j = i + 1; j < len; j++) {
if (j - i + 1 > length && valid(charArray, i, j)) {
left = i;
length = j - i + 1;
}
}
}
return s.substring(left, left + length);
}
// 判断是否回文串
private boolean valid(char[] charArray, int left, int right) {
while (left < right) {
if (charArray[left] != charArray[right]) {
return false;
}
left++;
right--;
}
return true;
}

这个答案慢肯定是慢,时间复杂度达到了 O(n^3) ,不慢才有鬼了。
解题方案二:中心扩散
上面的方案是从两边开始往中间夹,中心扩散的思想是从中间开始往两边进行扩散。
我在答案中找到了一个非常形象的图解,和大家分享一下:

解释一下这张图,现在假设有一个字符串 「acdbbdaa」 ,从第一个 b 位置开始找最长回文串。
- 首先往左寻找与当期位置相同的字符,直到遇到不相等为止。
- 然后往右寻找与当期位置相同的字符,直到遇到不相等为止。
- 最后左右双向扩散,直到左和右不相等。
这时我们找到了从 b 开始最长的回文子串,然后在程序中记录下来。
每一个位置开始都按这个方案去找最长的回文子串,最后得到的结果就是最长的回文子串。
public String longestPalindrome_1(String s) {
if (s == null || s.length() == 0) return "";
int length = s.length();
// 定义左右指针
int left = 0, right = 0;
// 定义长度
int len = 1;
// 定义最大开始位置和最长子串长度
int maxStart = 0, maxLen = 0;
for (int i = 0; i < length; i++) {
left = i - 1;
right = i + 1;
// 计算左边
while (left >= 0 && s.charAt(left) == s.charAt(i)) {
len++;
left--;
}
// 计算右边
while (right < length && s.charAt(right) == s.charAt(i)) {
len++;
right++;
}
// 两边一起扩散
while (left >= 0 && right < length && s.charAt(left) == s.charAt(right)) {
len += 2;
left--;
right++;
}
// 如果当前长度大于最大长度
if (len > maxLen) {
maxLen = len;
maxStart = left;
}
// 下次循环前重置 len
len = 1;
}
return s.substring(maxStart + 1, maxStart + 1 + maxLen);
}

解题方案三:动态规划
动态规划我的理解实际上就是一个把已经判断过的信息缓存起来的一种方案,很像我们在做 Web 开发的时候用到的 redis ,只是在答案中换成了一个矩阵或者说是二维数组。
如果一个字符串 s[l, r] 是一个回文串,那么 s[l + 1, r - 1] 一定也是一个回文串,相当于两头各去掉一个字符。
如果这时我们直接通过某种方式直接可以知道 s[l + 1, r - 1] 是一个回文串,那么只需要判断 s[i] 和 s[j] 相等就可以了。
所以就有了下面的代码:
public String longestPalindrome_2(String s) {
if (s == null || s.length() == 0) return s;
int length = s.length();
int maxStart = 0; //最长回文串的起点
int maxEnd = 0; //最长回文串的终点
int maxLen = 1; //最长回文串的长度
// 定义一个布尔矩阵
boolean[][] dp = new boolean[length][length];
for (int r = 1; r < length; r++) {
for (int l = 0; l < r; l++) {
if (s.charAt(r) == s.charAt(l) && (r - l <= 2 || dp[l + 1][r - 1] == true)) {
dp[l][r] = true;
if (r - l + 1 > maxLen) {
maxLen = r - l + 1;
maxStart = l;
maxEnd = r;
}
}
}
}
return s.substring(maxStart, maxEnd + 1);
}

可以看到耗时也是蛮多的。
答案中还给出了一种叫做 Manacher 算法的方案,原谅我比较菜,属实是没看懂,就不拿出来献丑了。
每日一道 LeetCode (48):最长回文子串的更多相关文章
- LeetCode:最长回文子串【5】
LeetCode:最长回文子串[5] 题目描述 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为1000. 示例 1: 输入: "babad" 输出: ...
- 【LeetCode】最长回文子串【动态规划或中心扩展】
给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1: 输入: "babad"输出: "bab"注意: " ...
- Java实现 LeetCode 5 最长回文子串
5. 最长回文子串 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1: 输入: "babad" 输出: "bab&quo ...
- [LeetCode] 5. 最长回文子串 ☆☆☆(最长子串、动态规划)
最长回文子串 (动态规划法.中心扩展算法) https://leetcode-cn.com/problems/longest-palindromic-substring/solution/xiang- ...
- 【LeetCode】最长回文子串-中心扩展法
[问题]给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 : 输入: "babad" 输出: "bab" 注意: ...
- leetcode python最长回文子串
回文的意思是正着念和倒着念一样,如:上海自来水来自海上,雾锁山头山锁雾,天连水尾水连天 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1: 输入: & ...
- [LeetCode] 5. 最长回文子串
题目链接:https://leetcode-cn.com/problems/longest-palindromic-substring/ 题目描述: 给定一个字符串 s,找到 s 中最长的回文子串.你 ...
- LeetCode 05 最长回文子串
题目 给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 1: 输入: "babad" 输出: "bab" 注意: ...
- 【leetcode 5. 最长回文子串】解题报告
方法一:中心扩展算法 解题思路:从左到右每一个字符都作为中心轴,然后逐渐往两边扩展,只要发现有不相等的字符,则确定了以该字符为轴的最长回文串,但需要考虑长度为奇数和偶数的不同情况的处理(长度为偶数时轴 ...
- 【LeetCode】最长回文子串-动态规划法
[问题]给定一个字符串 s,找到 s 中最长的回文子串.你可以假设 s 的最大长度为 1000. 示例 : 输入: "babad" 输出: "bab" 注意: ...
随机推荐
- sudo 提权漏洞(CVE-2019-14287)复现
(该文参考网络他人资料,仅为学习,不许用于非法用途) 一.环境 1.sudo版本小于1.8.28的Linux系统 2.sudo 是Linux系统命令,让普通账号以root身份去执行某些命令,比如:安装 ...
- Jmeter系列(56)- 详解 Weighted Switch Controller 权重控制器
如果你想从头学习Jmeter,可以看看这个系列的文章哦 https://www.cnblogs.com/poloyy/category/1746599.html 简单介绍 它能分配其子项目(Child ...
- IDEA创建动态Web项目
1.IDEA创建动态Web项目 1.1.使用IDEA创建动态Web项目,选择Java Enterprise,记得选择服务器,我这里使用的时tomcat 1.2记得勾选Web Application,其 ...
- [HAOI2007]修筑绿化带 题解
题意分析 给出一个 $m*n$ 的矩阵 $A$ ,要求从中选出一个 $a*b$ 的矩阵 $B$ ,再从矩阵 $B$ 中选出一个 $c*d$ 的矩阵 $C$ ,要求矩阵 $B,C$ 的边界不能重合,求矩 ...
- MySQL 字符类型
字符类型 MySQL提供了多种关于字符存储的类型,但是在大多数情况下我们只使用char和varchar即可 类型 大小 用途 CHAR 0-255字节 定长字符串 VARCHAR 0-65535 字节 ...
- Struts+Servlet+JDBC网上手机销售系统
项目描述 Hi,大家好,今天给大家分享一个<网上手机销售系统>.本系统一共分为前台和后台两大模块,两个模块之间虽然在表面上是相互独立的,但是在对数据库的访问上是紧密相连的,各个模块访问的是 ...
- VUE响应式原理-如何追踪变化
Vue 最独特的特性之一,是其非侵入性的响应式系统.数据模型仅仅是普通的 JavaScript 对象.而当你修改它们时,视图会进行更新.这使得状态管理非常简单直接 如何追踪变化 当你把一个普通的 Ja ...
- 让“不确定性”变得有“弹性”?基于弹性容器的AI评测实践
0. 前言 AI的场景丰富多彩,AI的评价方法百花齐放,这对于设计一套更通用的评测框架来说,是一个极大的挑战,需要兼顾不同的协议,不同的模型环境,甚至是不同的操作系统.本文分享了我们在AI评测路上的一 ...
- frozenset冻结集合函数
1.描述 frozenset()返回一个冻结的集合,冻结后不能添加.删除和修改. set()无序且不重复,是可以变的,有add.remove.扩展:删除重复数据,还可以计算交集.差集.并集等 2.函数 ...
- CA定义以及功能说明
当您访问以HTTPS开头的网站时,即表示正在使用CA.CA是Internet的重要组成部分.如果不存在CA,那么将无法安全在线购物以及使用网银在线业务等.什么是CA?CA具体是做什么的,又是如何确保您 ...