本文正在参加「Java主题月 - Java 刷题打卡」,详情查看 活动链接
验证回文字符串
题目描述
验证回文字符串(LeetCode 125)
给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
**说明:**本题中,我们将空字符串定义为有效的回文串。
示例 1:
输入: "A man, a plan, a canal: Panama"
输出: true
示例 2:
输入: "race a car"
输出: false
思路分析
本题考查的是语言中常用字符(串)相关 API 的使用,题目中提到了只考虑字母和数字字符,忽略字母的大小写,涉及到Character.isLetterOrDigit和Character.toLowerCase这两个API,本题我们使用双指针的解法,使用头尾指针,只考虑字母和数字字符,不是的话分别进行指针位移,然后统一转换成小写进行比较,判断是否是回文字符串。该解法的时间复杂度是,空间复杂度是。
代码展示
解法:使用双指针(头尾指针),遇到非字母和数字字符跳过,统一转换成小写进行对比,时间复杂度是,空间复杂度也是。
public boolean isPalindrome(String s) {
String temp = s.trim();
int length = temp.length();
int head = 0;
int tail = length - 1;
while(head < tail){
while(head < tail && !Character.isLetterOrDigit(temp.charAt(head))){
head++;
}
while(head < tail && !Character.isLetterOrDigit(temp.charAt(tail))){
tail--;
}
if(Character.toLowerCase(temp.charAt(head)) == Character.toLowerCase(temp.charAt(tail))){
head++;
tail--;
} else {
return false;
}
}
return true;
}
回文数
题目描述
回文数(LeetCode 9)
给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。例如,121 是回文,而 123 不是。
示例 1:
输入:x = 121
输出:true
示例 2:
输入:x = -121
输出:false
解释:从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
示例 3:
输入:x = 10
输出:false
解释:从右向左读, 为 01 。因此它不是一个回文数。
示例 4:
输入:x = -101
输出:false
进阶:你能不将整数转为字符串来解决这个问题吗?
思路分析
上面那道题我们验证了回文字符串,这道题是判断是不是回文数,如果把回文数转换成字符串,题目就变得很简单了,但是最好不要这么做,面试官肯定也不想看到这种解答,同时题目中还提到负数和一些其他情况不是回文数字,要注意这些情况的判断。同时还要注意字符串反转可能导致的溢出问题,所以考虑只反转一半。
例如,输入 1221,我们可以将数字 “1221” 的后半部分从 “21” 反转为 “12”,并将其与前半部分 “12” 进行比较,因为二者相同,我们得知数字 1221 是回文。
对于数字 1221,如果执行 1221 % 10,我们将得到最后一位数字 1,要得到倒数第二位数字,我们可以先通过除以 10 把最后一位数字从 1221 中移除,1221 / 10 = 122,再求出上一步结果除以 10 的余数,122 % 10 = 2,就可以得到倒数第二位数字。如果我们把最后一位数字乘以 10,再加上倒数第二位数字,1 * 10 + 2 = 12,就得到了我们想要的反转后的数字。如果继续这个过程,我们将得到更多位数的反转数字。
现在的问题是,我们如何知道反转数字的位数已经达到原始数字位数的一半?
由于整个过程我们不断将原始数字除以 10,然后给反转后的数字乘上 10,所以,当原始数字小于或等于反转后的数字时,就意味着我们已经处理了一半位数的数字了。
该解法的时间复杂度是,对于每次迭代,我们会将输入除以 10,因此时间复杂度为 。空间复杂度是。
代码展示
解法:该解法的时间复杂度是,空间复杂度也是。
public boolean isPalindrome(int x) {
if(x < 0 || (x != 0 && x % 10 == 0)){
return false;
}
int reverseNumber = 0;
while(x > reverseNumber){
reverseNumber = reverseNumber * 10 + x % 10;
x = x / 10;
}
return x == reverseNumber || (reverseNumber / 10 == x);
}
总结
验证回文字符串和回文数都很重要,是面试中比较常见的一类题,在验证回文字符串是可以使用双指针解法,但是在判断回文数的时候就应该注意,不应该将其转化为字符串,应该使用其他方式进行解答。