当前位置:网站首页>LeetCode刷题第10天字符串系列之《125回文串验证》
LeetCode刷题第10天字符串系列之《125回文串验证》
2022-08-11 03:42:00 【小机double】
LeetCode 125回文串验证
关于回文串,最早好像是在学校教C语言的时候就让我们写过类似的题目了,不过当时并没有考虑效率什么的,给出的字符串也只是全是字母。
回文串:从左往右和从右往左看是一样的,例如:abba。
题目描述
给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
说明:本题中,我们将空字符串定义为有效的回文串
要注意的是本题中只考虑字母和数字,所以可能存在其他字符需要先排除掉。
示例
输入: “A man, a plan, a canal: Panama”
输出:true
输入: “race a car”
输出: false
上面例子因为有其他字符和空格,可能不太容易看,而且题目也要求只考虑字母和数字字符,所以先去掉特殊字符并且不考虑大小写,如下:
amanaplanacanalpanama
可以发现从左到右和从右到左都是一样的。
而第二例子,就明显不一样
raceacar
题目解析
按照题目的描述,我们可以先将其他特殊字符给去除掉,简单的方法就是使用正则表达式的方式:
String newString = s.toLowerCase().replaceAll("[^0-9a-z]", "");
其中:
[^0-9a-z]
表示删除所有0-9,a-z之间的字符,即保存数字和小写字母。
处理之后就可以直接比较 第一个字符和最后一个字符,第二个字符和倒数第二个字符…是否相等,如果不相等则表明不是回文串,返回false。
处理方式可以如下:
- 创建一个队列和栈,先将所有的元素都入队列和进栈。之后根据队列(先进先出)和栈(先进后出)的性质,将队列的队头元素和栈的栈顶元素比较即可判断是否为回文串,代码如下:
public boolean isPalindrome(String s) {
if (s == "") {
return true;
}
String newString = s.toLowerCase().replaceAll("[^0-9a-z]", ""); //提前处理字符串
Queue<Character> queue = new ArrayDeque<>(); //创建队列
Stack<Character> stack = new Stack<>(); //创建栈
for (int i = 0; i < newString.length(); i++) {
queue.add(newString.charAt(i));
stack.add(newString.charAt(i));
}
for (int i = 0; i < newString.length(); i++) {
if (!queue.poll().equals(stack.pop())) {
//队头元素和栈顶元素比较
return false;
}
}
return true;
}
程序执行结果:

上面那种方法是之前学数据结构的时候教材上给的,其实完全没有必要去用到栈和队列,使用双指针直接比较即可,代码如下:
public boolean isPalindrome(String s) { if (s == "") { return true; } String newString = s.toLowerCase().replaceAll("[^0-9a-z]", ""); //提前处理字符串 for (int i = 0; i < newString.length() / 2; i++) { //遍历到一半即可 if (newString.charAt(i) != newString.charAt(newString.length() - i - 1)) { return false; } } return true; }程序执行结果:

可见这两种方式虽然可以解题,但是运行速度并不快,原因是因为在提前处理字符串是使用的是正则表达式,比较耗费时间(串的模式匹配)。
当然不使用正则表达式也是可以的,即不用提前处理字符串,只需在每次比较的过程中直接跳过特殊字符。这样就可以不用调用正则表达式来提前处理字符串了。代码如下:
public boolean isPalindrome(String s) {
if (s == "") {
return true;
}
s = s.toLowerCase();
int i = 0, j = s.length() - 1; //双指针
while (i < j) {
while (!isalnum(s.charAt(i)) && i < j) i++; //不是字符则跳过
while (!isalnum(s.charAt(j)) && i < j) j--;
if (s.charAt(i) != s.charAt(j)) {
return false;
}
//比较下一个
i++;
j--;
}
return true;
}
/** * 判断字符是否是数字或小写字母 * 模拟C++中的isalnum * 没有使用java中Character包装类中的相关方法,提高一点速度 */
public boolean isalnum(char ch) {
if (ch >= '0' && ch <= '9' || ch >= 'a' && ch <= 'z') {
return true;
}
return false;
}

边栏推荐
- 什么是机器强化学习?原理是什么?
- Interchangeability Measurements and Techniques - Calculation of Deviations and Tolerances, Drawing of Tolerance Charts, Selection of Fits and Tolerance Classes
- 【LeetCode】Day112-repetitive DNA sequence
- Interchangeability and Measurement Technology—Surface Roughness Selection and Marking Method
- 多串口RS485工业网关BL110
- 用户如何克服程序化交易中的情绪问题?
- Qnet Weak Network Test Tool Operation Guide
- 互换性测量与技术——偏差与公差的计算,公差图的绘制,配合与公差等级的选择方法
- 机器学习可以应用在哪些场景?机器学习有什么用?
- Enter the starting position, the ending position intercepts the linked list
猜你喜欢

作业8.10 TFTP协议 下载功能

rac备库双节点查询到的表最后更新时间不一致

Multi-merchant mall system function disassembly 26 lectures - platform-side distribution settings

二叉树相关代码题【较全】C语言

机器学习怎么学?机器学习流程

电商项目——商城限时秒杀功能系统

【FPGA】设计思路——I2C协议

Interchangeability and Measurement Technology—Surface Roughness Selection and Marking Method

LeetCode刷题第17天之《3 无重复字符的最长子串》

AI+Medical: Using Neural Networks for Medical Image Recognition and Analysis
随机推荐
MongoDB 基础了解(二)
What are port 80 and port 443?What's the difference?
【FPGA】设计思路——I2C协议
【愚公系列】2022年08月 Go教学课程 036-类型断言
轮转数组问题:如何实现数组“整体逆序,内部有序”?“三步转换法”妙转数组
MYSQLg高级------聚簇索引和非聚簇索引
MYSQLg advanced ------ clustered and non-clustered indexes
Audio codec, using FAAC to implement AAC encoding
What kind of programming trading strategy types can be divided into?
多串口RS485工业网关BL110
【C语言】入门
Qnet弱网测试工具操作指南
机器学习中什么是集成学习?
What is third-party payment?
常见布局效果实现方案
索引的创建、查看、删除
How to rebuild after pathman_config and pathman_config_params are deleted?
QueryDet: Cascading Sparse Query Accelerates Small Object Detection at High Resolution
常用认证机制
电力机柜数据监测RTU