【力扣经典面试题150道(java)】125. 验证回文串

题目

如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串

字母和数字都属于字母数字字符。

给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false

示例 1:

输入: s = “A man, a plan, a canal: Panama”
输出:true
解释:“amanaplanacanalpanama” 是回文串。

示例 2:

输入:s = “race a car”
输出:false
解释:“raceacar” 不是回文串。

示例 3:

输入:s = " "
输出:true
解释:在移除非字母数字字符之后,s 是一个空字符串 “” 。
由于空字符串正着反着读都一样,所以是回文串。

提示:

1 <= s.length <= 2 * 105
s 仅由可打印的 ASCII 字符组成

解题思路

思路一(对应方法一)

先进行string字符串的删改(转换大写为小写,删除字母数字以外的元素),然后再遍历字符串比较是否对称。

思路二(对应方法二)

直接在string字符串上判断,设置两个“指针”i,ji从前向后移动,j反之,每找到第n个字母数字对就进行比较是否一致,如果不一致return false,反之,结束遍历时输出true

易错点

(1) 对于方法二,如果两个元素不同,需要判断是大小写不同,还是“真”的不同(特别注意用ASCII码相差32来判断大小写不同的时候,注意排除数字和字母之间ASCII码相差32的情况

代码

方法一:for循环遍历(比较笨的方法)

时间复杂度:O(2*s.length+s’.length) (2是因为toLowerCase遍历了一遍字符串,s’.length指的是经过删除非字母数字之后的字符串长度)

class Solution {
    public boolean isPalindrome(String s) {
        int t = s.length();
        int i,temp;
        s = s.toLowerCase(); //转小写
        for (i=0;i<t;i++) {
            temp = s.charAt(i);
            if (temp<48 || temp>122 || (temp<97 && temp>57)) {//非字母数字
                if ((i+1)<t) //避免下标超出
                    s = s.substring(0,i)+s.substring(i+1,t); //删除
                else
                    s = s.substring(0,i); //删除
                t--;
                i--;//因为数组长度减少了,原来的i+1到了i的位置,为了避免漏判,这里i-1来使得i++后仍然对原来的i+1元素进行判断
            }
        }       
        
        for (i=0;i<t;i++) {
            if (s.charAt(i)!=s.charAt(t-1-i))
                return false;
        }
        return true;
    }
}
方法二:双指针

时间复杂度:O(s.length)

class Solution {
    public boolean isPalindrome(String s) {
        int t = s.length();
        int i,j = t-1;
        for (i=0;i<t;i++) {
            while (i<t && (s.charAt(i)<48 || s.charAt(i)>122 || (s.charAt(i)>57 && s.charAt(i)<65) || (s.charAt(i)>90 && s.charAt(i)<97))) 
            //非字母数字,while循环找到是字母数字为止
                i++;
            
            while (j>-1 && (s.charAt(j)<48 || s.charAt(j)>122 || (s.charAt(j)>57 && s.charAt(j)<65) || (s.charAt(j)>90 && s.charAt(j)<97)) 
            //非字母数字,while循环找到是字母数字为止
                j--;
            
            if (i>j || i>=t || j<0)
                break;
            
            if (s.charAt(i)!=s.charAt(j)) {//不相同
                if (s.charAt(i)<65 || s.charAt(j)<65) //排除字母和数字之间ASCII相差32的可能性
                    return false;
                else if (Math.abs(s.charAt(i)-s.charAt(j))!=32)//不同字母,且不是大小写问题
                    return false;
            }
                    
            j--;
            
        }
        return true;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值