这是我参与11月更文挑战的第15天,活动详情查看:2021最后一次更文挑战。
描述
给定一个长度为 n 的字符串,请编写一个函数判断该字符串是否回文。如果是回文请返回true,否则返回false。
字符串回文指该字符串正序与其逆序逐字符一致。
数据范围:0 < n ≤ 1000000
要求:空间复杂度 O(1),时间复杂度 O(n)
示例1
输入:
"absba"
返回值:
true
示例2
输入:
"ranko"
返回值:
false
示例3
输入:
"yamatomaya"
返回值:
false
示例4
输入:
"a"
复制
返回值:
true
备注:
字符串长度不大于1000000,且仅由小写字母组成
做题
主要分为两种情况:"abdccdba" or "abcdcda"
一看到这个对称,我就想到了使用栈去实现,或者遍历半个数组,直接对比 a[i] 和 a[n-i-1],n 为数组的长度。
很简单吧,我想大家都应该懂。
不过需要注意的是第二种情况,"abcdcda",可以说这个算法唯一的难点就是怎么同时兼容两种情况。
我第一时间想到的就是通过字符串的长度来判断,奇数就是第二种情况,偶数就是第一种情况,我觉得这个也是一个挺不错的解决方案。
又或者是判断 i 是否等于 n-i-1。
/**
* 循环半个数组
* @param str
* @return
*/
public boolean judge (String str) {
char[] chars = str.toCharArray();
int length = chars.length;
for (int i = 0; i < length/2; i++) {
int l=i;
int r=length-i-1;
if (chars[l]==chars[r]){
continue;
}else {
return false;
}
}
return true;
}
在我实际敲码的时候,发现并不需要去判断 i 是否等于 n-i-1 的情况,只要循环数组长度的一半就可以了,会忽略掉中间那个多出来的字符。
运行!
占用内存不过,超过了76%,运行时间还差一点。
再试
这个算法看起来还算不错了,但还是存在可以改进地方。
char[] chars = str.toCharArray();这里可以不获取 String 的 char 数组,而是直接调用 String 的 charAt 方法去获取字符,然后比较。
int l=i;
int r=length-i-1;
这一部分,r 可以在第一次赋值之后就一直采用自减的方式去更新,而不用每次都减这么多东西。
敲码!
**
* 优化
* @param str
* @return
*/
public boolean judge1 (String str) {
int length = str.length();
for (int l = 0,r=length-1; l < length/2; l++,r--) {
if (str.charAt(l)!=str.charAt(r)){
return false;
}
}
return true;
}
不错不错,运行时间减少了一丢丢,内存占用也增加了 12 个百分点。
也有运行情况下会出现运行时间不如第一种做法的情况,毕竟也是用时间换取了空间嘛,还算可以接受。
今天就到这里了。
这里是程序员徐小白,【每日算法】是我新开的一个专栏,在这里主要记录我学习算法的日常,也希望我能够坚持每日学习算法,不知道这样的文章风格您是否喜欢,不要吝啬您免费的赞,您的点赞、收藏以及评论都是我下班后坚持更文的动力。