力扣題目地址: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
不忘初心,砥礪前行。