[Leetcode][第647题][JAVA][回文子串][动态规划][中心扩展][Manacher 算法]

【问题描述】[中等]

在这里插入图片描述

【解答思路】

1. 暴力

首先明确如何判断一个字符串是否为回文字符串。第一个字符与最后一个字符相同,第二个字符与倒数第二个字符相同…关于中心位置轴对称。
本题要求一共有多少个回文子串,那么就需要判断,索引[i, j]的子串是不是回文子串,遍历所有这样[i, j]进行判断就可以找到回文子串的总数。这是暴力的做法。
首先如何判断[i, j]的子串是回文串,根据定义来判断即可。
定义boolean isPalindrome(char[] chars, int start, int end),第一个参数为原字符串的字符数组表示,第二第三个参数分别是字串的开始与结束索引。
在区间[start, end]上进行双指针的扫描,将关于中心位置对应的字符进行比较,如果发现有不相等说明不是回文子串。
循环结束没有发现对应位置不相等的字符,说明是回文串。
主函数中
外循环的i表示子串的长度,子串最长为s.length(),所以循环的条件为i <= s.length()。从长度2开始是因为,长度为1的子串都是回文子串,一共有s.length()个,最后加上即可。
内循环j表示子串的开始索引,那么其结束索引为j + i - 1。调用函数isPalindrome进行判断。
最后返回result + s.length(),将长度为1的子串都是回文子串的计数也算进行。

时间复杂度:O(N3) 空间复杂度:O(1)

public int countSubstrings(String s) {char[] chars = s.toCharArray();int result = 0;for (int i = 2; i <= s.length(); i++) {for (int j = 0; j + i - 1 < s.length(); j++)if (isPalindrome(chars, j, j + i - 1))result++;}return result + s.length();}private boolean isPalindrome(char[] chars, int start, int end) {for (int i = start, j = end; j > i; i++, j--) {if (chars[i] != chars[j])return false;}return true;}
2. 中心扩展

回文字符串关于中心对称,这个中心既可以是一个字符(比如子串的长度为奇数时),也可以是两个字符的中间(比如子串的长度为偶数时)。那么对于长度为n的字符串,其子串的中心一共有**n+(n-1)**个,n个是字母,n-1个是两个字母的间歇。
我们需要找到每一个可能的对称中心有能向外扩展出多少个回文子串。要想办法表示每一个回文中心,外扩的方式都一样。
回文中心与子串的奇偶性有关,想必要分情况讨论。
如果子串的长度为奇数,那么第一个子串只有一个字符,其左边界left与右边界right相等。
如果子串的长度为偶数,那么第一个子串有两个字符,其左边界left与右边界right的关系为right = left + 1。
所以可以通过奇偶性来控制初始时left与right的关系。
循环 for (int i = 0; i < chars.length * 2 - 1; i++),i表示每一个可能的回文中心,通过i的奇偶性来设置初始的left, right。内循环进行外扩,首先保证索引不超过数组边界,其次当前判断的两个字符相等。否则,当前[left, right]不是回文子串,向外扩的也不可能是。外扩的方式就是使left–, right++。

在这里插入图片描述

时间复杂度:O(N2) 空间复杂度:O(1)

public int countSubstrings3(String s) {char[] chars = s.toCharArray();int result = 0;for (int i = 0; i < chars.length * 2 - 1; i++) { // 对每个可能的回文中心进行循环int left = i / 2; // 当中心是两个字母的间歇时i%2 = 1;当中心是字母时 left==right都落在该字母的位置int right = left + i % 2;while(left >= 0 && right < chars.length && chars[left] == chars[right]){left--;right++;result++;}}return result;}
3. 动态规划

动态规划流程
第 1 步:设计状态
dp[i][j] i开始j结尾的是否为回文字符串
第 2 步:状态转移方程

for(int i = s.length()-1; i>=0; i--){for(int j = i+1; j<s.length(); j++){if(s.charAt(i) == s.charAt(j)){//i和j相邻的时候if(j - i == 1){dp[i][j] = true;}else{dp[i][j] = dp[i+1][j-1]}}else{dp[i][j] = false;}}
}

第 3 步:考虑初始化
在这里插入图片描述

第 4 步:考虑输出
统计 dp[i][j] = T 的个数

在这里插入图片描述

时间复杂度:O(N) 空间复杂度:O(1)

class Solution {public int countSubstrings(String s) {if(s == null || s.equals("")){return 0;}int n = s.length();boolean[][] dp = new boolean[n][n];int result = s.length();for(int i = 0; i<n; i++) dp[i][i] = true;for(int i = n-1; i>=0; i--){for(int j = i+1; j<n; j++){if(s.charAt(i) == s.charAt(j)) {//i和j相邻的时候if(j-i == 1){dp[i][j] = true;}else{dp[i][j] = dp[i+1][j-1]; }}else{dp[i][j] = false;}if(dp[i][j]){result++;}}}return result;}
}
2. Manacher 算法

在这里插入图片描述

时间复杂度:O(N) 空间复杂度:O(1)

class Solution {public int countSubstrings(String s) {int n = s.length();StringBuffer t = new StringBuffer("$#");for (int i = 0; i < n; ++i) {t.append(s.charAt(i));t.append('#');}n = t.length();t.append('!');int[] f = new int[n];int iMax = 0, rMax = 0, ans = 0;for (int i = 1; i < n; ++i) {// 初始化 f[i]f[i] = i <= rMax ? Math.min(rMax - i + 1, f[2 * iMax - i]) : 1;// 中心拓展while (t.charAt(i + f[i]) == t.charAt(i - f[i])) {++f[i];}// 动态维护 iMax 和 rMaxif (i + f[i] - 1 > rMax) {iMax = i;rMax = i + f[i] - 1;}// 统计答案, 当前贡献为 (f[i] - 1) / 2 上取整ans += f[i] / 2;}return ans;}
}

【总结】

1. 动态规划流程

第 1 步:设计状态
第 2 步:状态转移方程
第 3 步:考虑初始化
第 4 步:考虑输出
第 5 步:考虑是否可以状态压缩

2.暂时没有掌握 Manacher 算法(马拉车)

2.1 加# 变奇数长度 收尾加标识
2.2 初始化 中心扩展

3. 想好再下手 思考得多敲得少 边敲边想反而会耗费更多的时间

参考链接:https://leetcode-cn.com/problems/palindromic-substrings/solution/647java-bao-li-dpzhong-xin-kuo-zhan-xiang-jie-by-u/
参考链接:链接:https://leetcode-cn.com/problems/palindromic-substrings/solution/647-hui-wen-zi-chuan-dong-tai-gui-hua-fang-shi-qiu/
参考链接:https://leetcode-cn.com/problems/palindromic-substrings/solution/hui-wen-zi-chuan-by-leetcode-solution/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/424916.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

66-加一

给定表示非负整数的非空数字数组&#xff0c;加上整数的1。 存储数字使得最高有效数字位于列表的开头&#xff0c;并且数组中的每个元素包含单个数字。 您可以假设整数不包含任何前导零&#xff0c;除了数字0本身 例1&#xff1a; 输入&#xff1a; [1,2,3] 输出&#xff1a; […

玩转oracle 11g(52):Oracle导出导入表(.sql、.dmp文件)两种方法

提示&#xff1a;在导入sql和dmp文件之前&#xff0c;先建立用户&#xff0c;指明表空间。其中要注意用户名和表空间最好跟sql文件中的一样。 方法一&#xff1a;.sql文件的导出与导入 导出步骤 使用PL/SQL Developer登录你需要备份的数据库&#xff1b;选择工具->导出用…

第八章方差分析以及线性回归(2)

一元线性回归 变量间的关系 变量与变量之间的关系分为确定性关系和相关性关系。  确定性关系是指当自变量给定一个值的时候&#xff0c;就能计算出应变量的值。例如物体下落高度h与下落时间t的关系&#xff1a;h12gt2。  相关性关系是指变量之间的关系不确定&#xff0c;表…

Creating a Pulsing Circle Animation

Creating a Pulsing Circle Animation 原文 https://www.kirupa.com/animations/creating_pulsing_circle_animation.htm Outside of transitions that animate between states, we dont see a whole lot of actual animation in the many UIs we interact with. We dont have …

第四十九期:化繁为简的五种码农必备工具

如今&#xff0c;开发工具已成为了软件开发过程中必不可少的组成部分。本文将向您介绍当前软件开发市场上颇具影响力的五种化繁为简的码农必备工具。 不知您是否已经发现&#xff1a;那些以任务为中心的软件开发工作&#xff0c;会比独立的研究式开发复杂得多。针对软件产品的开…

【数据结构与算法】哈希算法

一、什么是哈希算法&#xff1f; 1.定义 将任意长度的二进制值串映射成固定长度的二进制值串&#xff0c;这个映射的规则就是哈希算法&#xff0c;而通过原始数据映射之后得到的二进制值串就是哈希值。 2.如何设计一个优秀的哈希算法&#xff1f; ①单向哈希&#xff1a; 从哈…

自然语言处理与文本检索

今天开始把翟成祥教授的文本检索课程做一下笔记。 说明&#xff1a;文章内容来源于课程视频和课程ppt。我只学习了课程没有做习题。文章不是翻译&#xff0c;是我对课程的理解。 nlp的主要内容 1 词语处理(lexical analysis part-of-speech tagging)&#xff1a;分词与词性标…

第五十期:工作强度超996,失业半年即出局,硅谷为何如此“嗜血”?

在硅谷&#xff0c;靠创业发财的人被称为中了“硅谷六合彩”&#xff0c;大多数个体的艰难挣扎&#xff0c;最终换来了硅谷长久的繁荣昌盛。 划重点 1、在硅谷&#xff0c;靠创业发财的人被称为中了“硅谷六合彩”。 2、谷歌的合同工必须比正式工早两小时到公司打卡&#xff…

分块入门笔记

祝劳动快乐 数列分块 数列分块入门5 蒲公英 莫队 小Z的袜子 数颜色/维护队列 乱搞 块速递推 块状链表 文本编辑器 树上分块 王室联邦 树的统计 转载于:https://www.cnblogs.com/HenryHuang-Never-Settle/p/10804588.html

【数据结构与算法】二叉树

树 1.树、二叉树 2.二叉查找树 3.平衡二叉树、红黑树 4.递归树 一、树 1.树的常用概念 根节点、叶子节点、父节点、子节点、兄弟节点&#xff0c;还有节点的高度、深度以及层数&#xff0c;树的高度。 2.概念解释 节点&#xff1a;树中的每个元素称为节点 父子关系&#xff…

第二十四期:面试问:Kafka为什么速度那么快?该怎么回答

针对Kafka的基准测试可以参考&#xff0c;Apache Kafka基准测试&#xff1a;每秒写入2百万(在三台廉价机器上)下面从数据写入和读取两方面分析&#xff0c;为什么Kafka速度这么快 Kafka的消息是保存或缓存在磁盘上的&#xff0c;一般认为在磁盘上读写数据是会降低性能的&#x…

leetcode 91. Decode Ways

91. Decode Ways https://www.cnblogs.com/grandyang/p/4313384.html 当前位置只可能来自前一个位置和前两个位置的dp&#xff0c;来自前一个位置的话&#xff0c;当前的数字不能是0&#xff1b;来自前两个位置&#xff0c;必须是1到26之间 class Solution { public:int numDec…

文本搜索

说明&#xff1a;文章内容来源于课程视频和课程ppt。我只学习了课程没有做习题。文章不是翻译&#xff0c;是我对课程的理解。 什么是文本搜索(Text Retrieval) 存在一个文档集&#xff0c;用户输入查询语句表示查询需求&#xff0c;搜索引擎返回搜索结果。这个过程一般被称为信…

【数据结构与算法】平衡二叉树、红黑树

1.树、二叉树 2.二叉查找树 3.平衡二叉树、红黑树 4.递归树 一&#xff0c;什么是“平衡二叉查找树” 1&#xff0c;定义&#xff1a;二叉树中任意一个节点的左右子树的高度相差不能大于1。 所以&#xff1a;完全二叉树&#xff0c;满二叉树都是平衡二叉树&#xff0c;非完全…

第五十一期:互联网不如国企,去BAT的程序员都是diao丝?

要说互联网是目前最热门的行业&#xff0c;应该没人反驳吧。尤其是技术&#xff0c;大家都想毕业后去BAT大厂&#xff0c;甚至比如微软、google等外企科技公司&#xff0c;学编程出身的高校学子&#xff0c;去国企的还是比较少。除非为了拿一线城市的户口&#xff0c;不然可能真…

linux基本命令2

一.文件打包与压缩工具 1.zip可以压缩多个文件或目录 压缩多个文件zip /tmp/backp.zip /etc/hosts /etc/inittab 案例如下[rootlocalhost tmp]# zip backup.zip file5 file6 adding: file5 (deflated 63%) adding: file6 (stored 0%)[rootlocalhost tmp]# ll backup.zip -rw-r-…

文档排序--相似度模型--VSM

说明&#xff1a;文章内容来源于课程视频和课程ppt。我只学习了课程没有做习题。文章不是翻译&#xff0c;是我对课程的理解。 上文提到文档排序函数是TR的核心。文档排序函数的实现有几种思路&#xff0c;其中一种是基于相似度的模型。这种模型具体是用空间向量模型(Vector Sp…

第二十五期:搞定Linux Shell文本处理工具,看完这篇集锦就够了

Linux Shell是一种基本功&#xff0c;由于怪异的语法加之较差的可读性&#xff0c;通常被Python等脚本代替。既然是基本功&#xff0c;那就需要掌握&#xff0c;毕竟学习Shell脚本的过程中&#xff0c;还是能了解到很多Linux系统的内容。 Linux Shell是一种基本功&#xff0c;由…

【数据结构与算法】递归树

1.树、二叉树 2.二叉查找树 3.平衡二叉树、红黑树 4.递归树 一、什么是递归树 如果我们把这个一层一层的分解过程画成图&#xff0c;它其实就是一棵树。我们给这棵树起一个名字&#xff0c;叫作递归树。 时间复杂度分析的递归树法 分析每一步核心操作的时间复杂度分析树高&…

【02】Kubernets:使用 kubeadm 部署 K8S 集群

写在前面的话 通过上一节&#xff0c;知道了 K8S 有 Master / Node 组成&#xff0c;但是具体怎么个组成法&#xff0c;就是这一节具体谈的内容。概念性的东西我们会尽量以实验的形式将其复现。 部署 K8S 集群 互联网常用的 K8S 集群部署方式&#xff1a; 1. kubeadm&#xff0…