当前位置: 首页 > 编程日记 > 正文

刻意练习:LeetCode实战 -- Task17. 最长回文子串

背景

本篇图文是LSGO软件技术团队组织的 第二期基础算法(Leetcode)刻意练习训练营 的打卡任务。本期训练营采用分类别练习的模式,即选择了五个知识点(数组、链表、字符串、树、贪心算法),每个知识点选择了 三个简单、两个中等、一个困难 等级的题目,共计三十道题,利用三十天的时间完成这组刻意练习。

本次任务的知识点:字符串

字符串或串(string) 是由数字、字母、下划线组成的一串字符。一般记为 s = “a1a2...an”(n >= 0)。它是编程语言中表示文本的数据类型。

通常以串的整体作为操作对象,如:在串中查找某个子串在该串中首次出现的位置、在串的某个位置上插入一个子串以及删除一个子串等。两个字符串相等的充要条件是:长度相等,并且各个对应位置上的字符都相等。串通常以顺序的方式进行存储与实现。


题目

  • 题号:5
  • 难度:中等
  • https://leetcode-cn.com/problems/longest-palindromic-substring/

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例 1

输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。

示例 2

输入: "cbbd"
输出: "bb"

示例 3

输入: "a"
输出: "a"

实现

回文是一个正读和反读都相同的字符串,例如,“aba”是回文,而“abc”不是。

第一种:暴力法,列举所有的子串,判断该子串是否为回文

  • 执行结果:超出时间限制
public class Solution
{public string LongestPalindrome(string s){if (string.IsNullOrEmpty(s))return string.Empty;if (s.Length == 1)return s;int start = 0;int end = 0;int len = int.MinValue;for (int i = 0; i < s.Length; i++){for (int j = i + 1; j < s.Length; j++){string str = s.Substring(i, j - i + 1);if (isPalindrome(str) && str.Length > len){len = str.Length;start = i;end = j;}}}return s.Substring(start, end - start + 1);}public bool isPalindrome(string s){for (int i = 0, len = s.Length / 2; i < len; i++){if (s[i] != s[s.Length - 1 - i])return false;}return true;}
}

第二种:动态规划

动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。

与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的(即下一个子阶段的求解是建立在上一个子阶段的解的基础上,进行进一步的求解)。若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间

我们可以用一个表来记录所有已解的子问题的答案。不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。这就是动态规划法的基本思路。

具体的动态规划算法多种多样,但它们具有相同的填表格式

使用记号 s[l, r] 表示原始字符串的一个子串,lr 分别是区间的左右边界的索引值,使用左闭、右闭区间表示左右边界可以取到。

dp[l, r] 表示子串 s[l, r](包括区间左右端点)是否构成回文串,是一个二维布尔型数组。

  • 当子串只包含 1 个字符,它一定是回文子串;
  • 当子串包含 2 个以上字符的时候:s[l, r] 是一个回文串,那么这个回文串两边各往里面收缩一个字符(如果可以的话)的子串 s[l + 1, r - 1] 也一定是回文串。

故,当 s[l] == s[r] 成立的时候,dp[l, r]的值由 dp[l + 1, r - l] 决定,这里还需要再多考虑一点点:“原字符串去掉左右边界”的子串的边界情况。

  • 当原字符串的元素个数为 3 的时候,如果左右边界相等,那么去掉它们以后,只剩下 1 个字符,它一定是回文串,故原字符串也一定是回文串;
  • 当原字符串的元素个数为 2 的时候,如果左右边界相等,那么去掉它们以后,只剩下 0 个字符,显然原字符串也一定是回文串。

综上,如果一个字符串的左右边界相等,判断为回文只需以下二者之一成立即可:

  • 去掉左右边界以后的字符串不构成区间,即s[l + 1, r - 1]包含元素少于2个,即:r - l <= 2
  • 去掉左右边界以后的字符串是回文串,即dp[l + 1, r - 1] == true

  • 状态:通过
  • 103 / 103 个通过测试用例
  • 执行用时: 232 ms, 在所有 C# 提交中击败了 46.79% 的用户
  • 内存消耗: 40.9 MB, 在所有 C# 提交中击败了 5.43% 的用户
public class Solution {public string LongestPalindrome(string s) {if (string.IsNullOrEmpty(s))return string.Empty;int len = s.Length;if (len == 1)return s;int longestPalindromelen = 1;string longestPalindromeStr = s.Substring(0, 1);bool[,] dp = new bool[len, len];for (int r = 1; r < len; r++){for (int l = 0; l < r; l++){if (s[r] == s[l] && (r - l <= 2 || dp[l + 1, r - 1] == true)){dp[l, r] = true;if (longestPalindromelen < r - l + 1){longestPalindromelen = r - l + 1;longestPalindromeStr = s.Substring(l, r - l + 1);}}}}return longestPalindromeStr;        }
}

Python 语言

  • 执行结果:通过
  • 执行用时:3392 ms, 在所有 Python3 提交中击败了 43.87% 的用户
  • 内存消耗:21.2 MB, 在所有 Python3 提交中击败了 18.81% 的用户
class Solution:def longestPalindrome(self, s: str) -> str:count = len(s)if count == 0 or count == 1:return slongestPalindromelen = 1longestPalindromeStr = s[0:1]dp = [[False] * count for i in range(count)]for r in range(1, count):for l in range(0, r):if s[r] == s[l] and (r - l <= 2 or dp[l + 1][r - 1] == True):dp[l][r] = Trueif longestPalindromelen < r - l + 1:longestPalindromelen = r - l + 1longestPalindromeStr = s[l:l + longestPalindromelen]return longestPalindromeStr

参考文献

  • https://leetcode-cn.com/problems/longest-palindromic-substring/solution/zhong-xin-kuo-san-dong-tai-gui-hua-by-liweiwei1419/

往期活动

LSGO软件技术团队会定期开展提升编程技能的刻意练习活动,希望大家能够参与进来一起刻意练习,一起学习进步!

  • Python基础刻意练习活动即将开启,你参加吗?
  • Task01:变量、运算符与数据类型
  • Task02:条件与循环
  • Task03:列表与元组
  • Task04:字符串与序列
  • Task05:函数与Lambda表达式
  • Task06:字典与集合
  • Task07:文件与文件系统
  • Task08:异常处理
  • Task09:else 与 with 语句
  • Task10:类与对象
  • Task11:魔法方法
  • Task12:模块

我是 终身学习者“老马”,一个长期践行“结伴式学习”理念的 中年大叔

我崇尚分享,渴望成长,于2010年创立了“LSGO软件技术团队”,并加入了国内著名的开源组织“Datawhale”,也是“Dre@mtech”、“智能机器人研究中心”和“大数据与哲学社会科学实验室”的一员。

愿我们一起学习,一起进步,相互陪伴,共同成长。

后台回复「搜搜搜」,随机获取电子资源!
欢迎关注,请扫描二维码:

相关文章:

CvBlobTrackerCC 多目标跟踪算法简析

&#xff08;1&#xff09;跟踪器的建立&#xff1a;对新产生的目标&#xff0c;且宽&#xff08;高&#xff09;大于5时&#xff0c;建立跟踪器 &#xff08;2&#xff09;Kalman滤波&#xff1a;用Kalman滤波器对目标当前的方位、大小做出预测 目标特征矢量采用(x, y, dx, dy…

linux基础学习(二)

------------------------------------------------------------------------------------------------------------------------------------------------0.真机远程管理虚拟机telnet 明文传输 tcp 23ssh 加密传输 tcp 22ssh -X root172.25.0.11 //真机远程管理 ser…

ui设计培训需要什么基础?如何入门学习?

​ UI设计是一种直观面向用户的一个技术岗位&#xff0c;在互联网公司&#xff0c;UI设计岗位是不可或缺的&#xff0c;那么对于零基础想要学习UI设计的同学来说&#xff0c;ui设计培训需要什么基础?如何入门学习呢?我们来看看下面的详细介绍。 ​  ui设计培训需要什么基础…

SQL Server日志清除的两种方法 .

在使用过程中大家经常碰到数据库日志非常大的情况&#xff0c;在这里介绍了两种处理方法…… 方法一 一般情况下&#xff0c;SQL数据库的收缩并不能很大程度上减小数据库大小&#xff0c;其主要作用是收缩日志大小&#xff0c;应当定期进行此操作以免数据库日志过大。 1、设置数…

刻意练习:LeetCode实战 -- Task18. 正则表达式匹配

背景 本篇图文是LSGO软件技术团队组织的 第二期基础算法&#xff08;Leetcode&#xff09;刻意练习训练营 的打卡任务。本期训练营采用分类别练习的模式&#xff0c;即选择了五个知识点&#xff08;数组、链表、字符串、树、贪心算法&#xff09;&#xff0c;每个知识点选择了…

CentOS7启动图形界面

1.yum groupinstall "GNOME Desktop" -y 2.systemctl get-default 3.systemctl set-default graphical.target 4.systemctl get-default 5.reboot

Java培训学习步骤有哪些

最近几年&#xff0c;有很多学习java技术的同学都有过半途而废的想法&#xff0c;认为java零基础是很难学会的&#xff0c;其实出现这样的问题&#xff0c;最主要的原因就是学习方法有问题&#xff0c;下面小编整理的Java培训学习步骤&#xff0c;希望能够帮助大家更有效的学习…

extjs 4 tab panel得strip在IE下右偏解决办法

这是受 align"center" 影响造成的转载于:https://www.cnblogs.com/rav009/archive/2011/12/31/5131240.html

Vbox共享文件夹不显示了

博主之前装的虚拟机没啥问题&#xff0c;按部就班&#xff0c;打开“我的电脑”可以看到主机上的共享文件夹&#xff0c;最近重装了一波&#xff0c;各种问题就来了&#xff0c;包括共享文件夹设置好后&#xff0c;看不见了。 介绍比较麻烦的方案&#xff0c;就是打开“我的电脑…

刻意练习:LeetCode实战 -- Task19. 相同的树

背景 本篇图文是LSGO软件技术团队组织的 第二期基础算法&#xff08;Leetcode&#xff09;刻意练习训练营 的打卡任务。本期训练营采用分类别练习的模式&#xff0c;即选择了五个知识点&#xff08;数组、链表、字符串、树、贪心算法&#xff09;&#xff0c;每个知识点选择了…

找Java培训机构需要注意那些

​ java技术在互联网行业已经是众所周知的一个编程热门技术&#xff0c;市面上也出现了很多java培训机构&#xff0c;那么想要找到一个适合自己且比较专业的java培训机构应该注意哪些呢?下面小编就为大家详细的介绍一下找Java培训机构需要注意那些? ​  找Java培训机构需要…

字符串的最大相似匹配

字符串的最大相似匹配计划中&#xff0c;kmp完后&#xff0c;本篇继续。。。转载于:https://www.cnblogs.com/springmvc-hibernate/archive/2011/12/31/2484048.html

刻意练习:LeetCode实战 -- Task20. 对称二叉树

背景 本篇图文是LSGO软件技术团队组织的 第二期基础算法&#xff08;Leetcode&#xff09;刻意练习训练营 的打卡任务。本期训练营采用分类别练习的模式&#xff0c;即选择了五个知识点&#xff08;数组、链表、字符串、树、贪心算法&#xff09;&#xff0c;每个知识点选择了…

洛谷 P1598 垂直柱状图【字符串+模拟】

P1598 垂直柱状图 题目描述 写一个程序从输入文件中去读取四行大写字母&#xff08;全都是大写的&#xff0c;每行不超过72个字符&#xff09;&#xff0c;然后用柱状图输出每个字符在输入文件中出现的次数。严格地按照输出样例来安排你的输出格式。 输入输出格式 输入格式&…

java开发培训中消息中间件的优势有哪些

系统解耦 交互系统之间没有直接的调用关系&#xff0c;只是通过消息传输&#xff0c;故系统侵入性不强&#xff0c;耦合度低。 提高系统响应时间 例如原来的一套逻辑&#xff0c;完成支付可能涉及先修改订单状态、计算会员积分、通知物流配送几个逻辑才能完成;通过MQ 架构设计&…

UIView 的 autoresizingMask 属性 详解。

在 UIView 中有一个autoresizingMask的属性&#xff0c;它对应的是一个枚举的值&#xff08;如下&#xff09;&#xff0c;属性的意思就是自动调整子控件与父控件中间的位置&#xff0c;宽高。 enum { UIViewAutoresizingNone 0, UIViewAutoresizingFle…

刻意练习:LeetCode实战 -- Task21. 二叉树的最大深度

背景 本篇图文是LSGO软件技术团队组织的 第二期基础算法&#xff08;Leetcode&#xff09;刻意练习训练营 的打卡任务。本期训练营采用分类别练习的模式&#xff0c;即选择了五个知识点&#xff08;数组、链表、字符串、树、贪心算法&#xff09;&#xff0c;每个知识点选择了…

spring中@value注解需要注意

转自&#xff1a;https://blog.csdn.net/qiuhan/article/details/47089329 首先&#xff0c;value需要参数&#xff0c;这里参数可以是两种形式&#xff1a;Value("#{configProperties[t1.msgname]}")或者Value("${t1.msgname}")&#xff1b; 其次&#xf…

学Java需要用到的软件快收藏!

java编程语言学起来是比较繁琐的&#xff0c;很多java工程师不管是工作还是学习&#xff0c;都会用到一些辅助工具&#xff0c;对于想要学习java技术的人来说&#xff0c;利用java辅助软件学习会比较更有效率&#xff0c;下面小编就为大家一一整理一下学Java需要用到的软件有哪…

刻意练习:LeetCode实战 -- Task22. 二叉树的中序遍历

背景 本篇图文是LSGO软件技术团队组织的 第二期基础算法&#xff08;Leetcode&#xff09;刻意练习训练营 的打卡任务。本期训练营采用分类别练习的模式&#xff0c;即选择了五个知识点&#xff08;数组、链表、字符串、树、贪心算法&#xff09;&#xff0c;每个知识点选择了…

Oracle round函数是什么意思?怎么运用?

如何使用 Oracle Round 函数 (四舍五入) 描述 : 传回一个数值&#xff0c;该数值是按照指定的小数位元数进行四舍五入运算的结果。 SELECT ROUND( number, [ decimal_places ] ) FROM DUAL 参数: number : 欲处理之数值 decimal_places : 四舍五入 , 小数取几位 ( 预设为 0 ) S…

Spring MVC前后端的数据传输

本篇文章主要介绍了Spring MVC中如何在前后端传输数据。 后端 ➡ 前端 在Spring MVC中这主要通过Model将数据从后端传送到前端&#xff0c;一般的写法为&#xff1a; RequestMapping(value "/index", method RequestMethod.POST) public String index(Model model)…

参加java培训,要避免这几个误区!

​ java技术在近几年学习的人越来越多&#xff0c;小编在这里提醒同学们&#xff0c;想要学好java技术&#xff0c;除了报班系统培训之外&#xff0c;还要找到适合自己的学习方法&#xff0c;以下几点误区同学们一定要避免! ​  参加java培训&#xff0c;要避免这几个误区! 1…

SQL优化整理。

其实SQL能力很差劲&#xff0c;简单查询还成&#xff0c;复杂查询以及优化&#xff0c;基本脑子里没有概念。了解一下概念&#xff0c;然后打算找本理论书好好看看。 先到处找了些优化的sql&#xff0c;整理出来&#xff0c;记录一下。1、对查询进行优化&#xff0c;应尽量避免…

PHP开发框架之YII框架学习——碾压ThinkPHP不是梦

前 言 JRedu 程序猿是一种慵懒的生物&#xff01;能少敲一行代码&#xff0c;绝对不会多敲一个字符&#xff01;所以&#xff0c;越来越多的开发框架应运而生&#xff0c;在帮助我们完成功能的同时&#xff0c;极大程度上也帮我们节省了人力物力&#xff0c;而且也提高了系统的…

刻意练习:LeetCode实战 -- 二叉树的前序遍历

背景 今天&#xff0c;第二期基础算法&#xff08;Leetcode&#xff09;刻意练习训练营 的打卡任务是二叉树的中序遍历&#xff0c;由于二叉树的遍历方式通常来说有四种&#xff1a;前序遍历、中序遍历、后序遍历以及层次遍历&#xff0c;而LeetCode也有二叉树的前序遍历题目&…

接口测试要如何做数据准备

数据准备是接口测试过程中不可或缺的一步&#xff0c;也是花费时间很长的工作&#xff0c;因为程序的功能就是处理数据。那么在接口测试中&#xff0c;我们要怎样来准备数据呢?小编整理了以下一些关于数据准备的方法&#xff0c;希望对大家能有所帮助。 数据准备分为两种类型&…

刻意练习:LeetCode实战 -- 二叉树的后序遍历

背景 今天&#xff0c;第二期基础算法&#xff08;Leetcode&#xff09;刻意练习训练营 的打卡任务是二叉树的中序遍历&#xff0c;由于二叉树的遍历方式通常来说有四种&#xff1a;前序遍历、中序遍历、后序遍历以及层次遍历&#xff0c;而LeetCode也有二叉树的后序遍历题目&…

数据库加锁(转)

1 如何锁一个表的某一行 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED SELECT * FROM table ROWLOCK WHERE id 1 2 锁定数据库的一个表 SELECT * FROM table WITH (HOLDLOCK) 加锁语句&#xff1a; sybase: update 表 set col1col1 where 10 ; MSSQL: select col1 from …

学好web前端开发要注意哪些问题

web前端学起来是比较困难的&#xff0c;当然想要学好web前端技术&#xff0c;那么有一些注意事项一定是要看的&#xff0c;下面小编就为大家详细的介绍一下学好web前端开发要注意哪些问题? ​  学好web前端开发要注意哪些问题? 基础&#xff1a;无论做什么都一定要有扎实的…