力扣题目地址:https://leetcode-cn.com/problems/palindrome-number/
首先看题目:
判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
示例:
输入: 121
输出: true
输入: -121
输出: false
解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
输入: 10
输出: false
解释: 从右向左读, 为 01 。因此它不是一个回文数。
解决思路:
首先,我的第一想法是将int转换为String类型,然后比较对应位置的值是否相等。(从示例2来看,负数可以全部排除,0可以确定是正确的。)
开始我们的解题之旅:
- 判断传入 x 的值的正负。
- int转换为String。
- 判断对应位置的值是否相等。
代码实现如下:
/**
* 回文数 转为字符然后遍历字符串
* @param x
* @author GeYuxuan 2020-03-04 22:15:41
* @return int
*/
public boolean isPalindrome(int x) {
//1.判断传入 x 的值的正负
if(x<0){
return false;
}else if(x==0){
return true;
}else{
//2. int转换为String
String request = String.valueOf(x);
int size = request.length();
for(int i = 0; i < size; i++) {
//3. 判断对应位置的值是否相等
//比如:121 的第一个和第三个就是对应的
//关于奇偶的问题:如果是奇数取的是同一个位置的值
//如果是偶数,则比较两个位置的值
if(request.charAt(i) == request.charAt(size-i-1)){
continue;
}else{
return false;
}
}
return true;
}
}
然后我们测试一下:
public static void main(String[] args) {
int x = 1111;
Solution solution = new Solution();
System.out.println(solution.isPalindrome(x));
}
打印结果: true
ok,这就是我自己能想到的最常规的解法了。
看完官方题解之后,我发现他们用了一种很巧妙的方法来判断数字如何遍历到了中间位置;所以这里也一起分享给大家。
解决思路:
不进行数字转换,首先利用负数和末尾带0的数字不可能为回文数,排除一部分。然后通过取模运算和除法运算获取一个反转数,将反转数和剩余值比较,当剩余值小于等于反转值时,说明取到了中间位(循环终止条件)。
获取反转数思路:新建一个反转值0,然后对原值先进行取模运算(对10取模),获取当前的末尾值,然后将当前反转值前进一位(乘以10)并加上当前末尾值。获得当前反转数后,要将原值除去末尾值(因为被取到反转值中),原值缩小一位(除以10)。
示例:1221
循环终止条件:当原值小于等于反转值时,说明取到了中间位
第一次循环:
反转值:0
原值:1221
原值取模获取当前末尾值:1221 % 10 = 1
反转值(前进一位并加上当前末尾值):0 * 10 + 1 = 1
原值(缩小一位):1221 / 10 = 122
原值大于反转值:122 > 1
第二次循环:
反转值:1
原值:122
原值取模获取当前末尾值:122 % 10 = 2
反转值(前进一位并加上当前末尾值):1 * 10 + 2 = 12
原值(缩小一位):122 / 10 = 12
原值等于反转值:12 = 12
循环终止
- 新建一个反转值0。
- 对原值先进行取模运算(对10取模),获取当前的末尾值,然后将当前反转值前进一位(乘以10)并加上当前末尾值。
- 获得当前反转数后,要将原值除去末尾值(因为被取到反转值中),原值缩小一位(除以10)。
- 循环直到原值小于等于反转值。
代码实现如下:
/**
* 回文数-数字除法+取模
* @param x
* @author GeYuxuan 2020-03-04 22:15:41
* @return int
*/
public boolean isPalindrome1(int x) {
//1.新建一个反转值0
int revertedNumber = 0;
if(x < 0 || (x % 10 ==0 && x != 0)){
return false;
}else if(x==0){
return true;
}else{
//4.循环直到原值小于等于反转值
while (x>revertedNumber){
//2.对原值先进行取模运算(对10取模)
//获取当前的末尾值,将当前反转值前进一位(乘以10)
//加上当前末尾值
revertedNumber = revertedNumber*10+x%10;
//3.获得当前反转数
//原值除去末尾值(因为被取到反转值中)
//原值缩小一位(除以10)
x/=10;
}
//当数字长度为奇数时,通过反转值缩小一位,去除处于中位的数字。
return x==revertedNumber || x ==revertedNumber/10;
}
}
最后一步奇偶数的解释如下:
示例:1221
循环终止条件:当原值小于等于反转值时,说明取到了中间位
第一次循环:
反转值:0
原值:12321
原值取模获取当前末尾值:12321 % 10 = 1
反转值(前进一位并加上当前末尾值):0 * 10 + 1 = 1
原值(缩小一位):12321 / 10 = 1232
原值大于反转值:1232 > 1
第二次循环:
反转值:1
原值:1232
原值取模获取当前末尾值:1232 % 10 = 2
反转值(前进一位并加上当前末尾值):1 * 10 + 2 = 12
原值(缩小一位):1232 / 10 = 12
原值大于反转值:123 > 12
第二次循环:
反转值:12
原值:123
原值取模获取当前末尾值:123 % 10 = 3
反转值(前进一位并加上当前末尾值):12 * 10 + 3 = 123
原值(缩小一位):123 / 10 = 12
原值小于反转值:12 < 123
循环终止
当数字长度为奇数时,通过反转值缩小一位,去除处于中位的数字。
反转值(缩小一位):123 / 10 = 12
原值:12
不忘初心,砥砺前行。