【每日算法】NC141 判断是否为回文字符串

433 阅读3分钟

这是我参与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 的情况,只要循环数组长度的一半就可以了,会忽略掉中间那个多出来的字符。

运行!

image.png 占用内存不过,超过了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;
}

image.png

不错不错,运行时间减少了一丢丢,内存占用也增加了 12 个百分点。

也有运行情况下会出现运行时间不如第一种做法的情况,毕竟也是用时间换取了空间嘛,还算可以接受。

今天就到这里了。

这里是程序员徐小白,【每日算法】是我新开的一个专栏,在这里主要记录我学习算法的日常,也希望我能够坚持每日学习算法,不知道这样的文章风格您是否喜欢,不要吝啬您免费的赞,您的点赞、收藏以及评论都是我下班后坚持更文的动力。