題目:
題目地址:https://leetcode-cn.com/problems/palindrome-number/
問題描述:
判斷一個整數(shù)是否是回文數(shù)?;匚臄?shù)是指正序(從左向右)和倒序(從右向左)讀都是一樣的整數(shù)。
示例 1:
輸入: 121
輸出: true
示例 2:輸入: -121
輸出: false
解釋: 從左向右讀, 為 -121 。 從右向左讀, 為 121- 。因此它不是一個回文數(shù)。
示例 3:輸入: 10
輸出: false
解釋: 從右向左讀, 為 01 。因此它不是一個回文數(shù)。進階:
你能不將整數(shù)轉(zhuǎn)為字符串來解決這個問題嗎?
我的解題思路:
1.數(shù)字逐位對比
通過除法和取余獲得數(shù)字的最高位和最低位進行比較,例如輸入的數(shù)字是12321
- 12321/10000=1 獲得最高位
- 12321%10=1 獲得最低位
- 接下來去掉最高位和最低位的數(shù)字:
- 12321%10000=2321 去掉了最高位
- 2321%10 =232 去掉了最低位
- 循壞
代碼如下:
public static boolean isPalindrome(int x) {
//如果x是負數(shù),則一定不是回文數(shù)
if (x < 0) {
return false;
}
int a = 1;
while (x / a >= 10) {
a *= 10;
}
int left = 0;//左邊第一位,也就是最高位
int right = 0;//右邊第一位,也就是最低位
while (a > 0) {
left = x / a;
right = x % 10;
if (left != right) {
return false;
}
x = (x % a) / 10;
a /= 100;
}
return true;
}
2.字符串反轉(zhuǎn)
這種方法一開始其實沒有想到,但是題目的進階提示居然暗示了:“你能不將整數(shù)轉(zhuǎn)為字符串來解決這個問題嗎?”。于是想到用字符串反轉(zhuǎn)的方法來解決其實更簡單。
使用StringBuilder的reverse方法就能反轉(zhuǎn)字符串。
代碼如下:
public static boolean isPalindrome(int x) {
String string = new StringBuilder(String.valueOf(x)).reverse().toString();
return string.equals(String.valueOf(x));
}
兩行代碼就能解決,不過這種方法的性能比較差,執(zhí)行時間比直接用數(shù)字逐位比較的方法要久。
網(wǎng)上其他題解中更優(yōu)化的思路:
進階解法---巧妙解法
直觀上來看待回文數(shù)的話,就感覺像是將數(shù)字進行對折后看能否一一對應(yīng)。
所以這個解法的操作就是 取出后半段數(shù)字進行翻轉(zhuǎn)。
這里需要注意的一個點就是由于回文數(shù)的位數(shù)可奇可偶,所以當它的長度是偶數(shù)時,它對折過來應(yīng)該是相等的;當它的長度是奇數(shù)時,那么它對折過來后,有一個的長度需要去掉一位數(shù)(除以 10 并取整)。
具體做法如下:
每次進行取余操作 ( %10),取出最低的數(shù)字:y = x % 10
將最低的數(shù)字加到取出數(shù)的末尾:revertNum = revertNum * 10 + y
每取一個最低位數(shù)字,x 都要自除以 10
判斷 x 是不是小于 revertNum ,當它小于的時候,說明數(shù)字已經(jīng)對半或者過半了
最后,判斷奇偶數(shù)情況:如果是偶數(shù)的話,revertNum 和 x 相等;如果是奇數(shù)的話,最中間的數(shù)字就在revertNum 的最低位上,將它除以 10 以后應(yīng)該和 x 相等。
class Solution {
public boolean isPalindrome(int x) {
//思考:這里大家可以思考一下,為什么末尾為 0 就可以直接返回 false
//答:因為數(shù)字的最高位不可能是0,如果最低位是0那肯定就不是回文數(shù)了
if (x < 0 || (x % 10 == 0 && x != 0)) return false;
int revertedNumber = 0;
while (x > revertedNumber) {
revertedNumber = revertedNumber * 10 + x % 10;
x /= 10;
}
return x == revertedNumber || x == revertedNumber / 10;
}
}
這種思路很巧妙,循壞次數(shù)大概只需要普通做法的一半,性能更好。