当前位置:网站首页>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;
}
边栏推荐
- 二叉树相关代码题【较全】C语言
- How does MSP430 download programs to the board?(IAR MSPFET CCS)
- What should I do if the channel ServerID is incorrect when EasyCVR is connected to a Hikvision Dahua device and selects another cluster server?
- A simple JVM tuning, learn to write it on your resume
- MYSQLg高级------回表
- C语言 recv()函数、recvfrom()函数、recvmsg()函数
- 基于改进YOLOv5轻量化的烟火检测
- 浅析一下期货程序化交易好还是手工单好?
- LeetCode热题(12.买卖股票的最佳时机)
- 你不知道的 console.log 替代品
猜你喜欢
Interchangeability and Measurement Technology—Surface Roughness Selection and Marking Method
The last update time of the tables queried by the two nodes of the rac standby database is inconsistent
互换性测量与技术——偏差与公差的计算,公差图的绘制,配合与公差等级的选择方法
MongoDB 基础了解(二)
树莓派入门(5)系统备份
Basic understanding of MongoDB (2)
阿里低代码框架 lowcode-engine 之自定义物料篇
【愚公系列】2022年08月 Go教学课程 036-类型断言
机器学习可以应用在哪些场景?机器学习有什么用?
[FPGA] Design Ideas - I2C Protocol
随机推荐
STC8H development (15): GPIO drive Ci24R1 wireless module
How does MSP430 download programs to the board?(IAR MSPFET CCS)
es-head插件插入查询以及条件查询(五)
typedef定义结构体数组类型
js 将字符串作为js执行代码使用
Interchangeability and Measurement Techniques - Tolerance Principles and Selection Methods
常见布局效果实现方案
Build Zabbix Kubernetes cluster monitoring platform
程序化交易的策略类型可以分为哪几种?
Detailed explanation of VIT source code
怎么删除语句审计日志?
元素的BFC属性
What are port 80 and port 443?What's the difference?
机器学习是什么?详解机器学习概念
常用认证机制
互换性测量技术-几何误差
[yu gong series] Go program 035-08 2022 interfaces and inheritance and transformation and empty interface
电力机柜数据监测RTU
云平台下ESB产品开发步骤说明
【FPGA】day19-二进制转换为十进制(BCD码)