題目
判斷一個整數是否是迴文數。迴文數是指正序(從左向右)和倒序(從右向左)讀都是一樣的整數。
示例 1:
輸入: 121
輸出: true
示例 2:
輸入: -121
輸出: false
解釋: 從左向右讀, 爲 -121 。 從右向左讀, 爲 121- 。因此它不是一個迴文數。
示例 3:
輸入: 10
輸出: false
解釋: 從右向左讀, 爲 01 。因此它不是一個迴文數。
進階:
你能不將整數轉爲字符串來解決這個問題嗎?
思考
我第一感覺就是首先負數肯定不是,然後我就思考到了,和我那個字符串倒序,豈不是像的一批,負數直接捨棄,正數倒序後和原數一樣,不就是題目中的意思了。
解題
class Solution {
public:
bool isPalindrome(int x) {
int x2;
x2=x;
if (x2<0)
return false;
int pop=0;
long long int rev=0;
while(x!=0){
pop=x%10;
x/=10;
rev=rev*10+pop;
}
cout<<rev;
if(rev==x2)
return true;
else
return false;
}
};
反思
我的思路是正確的,最終也提交成功了,有幾點比較有意思。
- 一開始在最終的是rev和x進行比較,怎麼着都得不到結果,最後發現是x其實已經變化,所以我又添加了一個x2,解決了這一問題。
- 記得7的整數逆序就有這個溢出問題,這次leetcode也正是把那個int的最大值進行測試,果不然,我報錯了,最後我轉念一想將,rev改成了longlongint,解決了這一問題。
- 比較搞笑了這個,最後那個if語句,我本想用一個?:三目運算符,覺得代碼簡潔一點,可尷尬的是,三目用算符的後兩個條件是隻能是計算表達式,我寫的return表達式就會瘋狂報錯,也是屬實尷尬了。
官方題解
官方題解和我的思路一致,就是整數反轉後,然後和原來的比較,官方也提到了這個數據溢出的問題,我呢是採用了longlongint的方法解決這一問題,官方提到一個有趣的方法,把數字只反轉一半
具體思路是這樣:
代碼:
class Solution {
public:
bool isPalindrome(int x) {
// 特殊情況:
// 如上所述,當 x < 0 時,x 不是迴文數。
// 同樣地,如果數字的最後一位是 0,爲了使該數字爲迴文,
// 則其第一位數字也應該是 0
// 只有 0 滿足這一屬性
if (x < 0 || (x % 10 == 0 && x != 0)) {
return false;
}
int revertedNumber = 0;
while (x > revertedNumber) {
revertedNumber = revertedNumber * 10 + x % 10;
x /= 10;
}
// 當數字長度爲奇數時,我們可以通過 revertedNumber/10 去除處於中位的數字。
// 例如,當輸入爲 12321 時,在 while 循環的末尾我們可以得到 x = 12,revertedNumber = 123,
// 由於處於中位的數字不影響迴文(它總是與自己相等),所以我們可以簡單地將其去除。
return x == revertedNumber || x == revertedNumber / 10;
}
};
- 我覺得官方最後一步對於奇數的處理還是蠻巧妙的,除以10來判斷是否和x相等,來解決奇數的問題
- 對於何時是數字的一半的理解也很巧妙:由於整個過程我們不斷將原始數字除以 10,然後給反轉後的數字乘上 10,所以,當原始數字小於或等於反轉後的數字時,就意味着我們已經處理了一半位數的數字了。
複雜度分析
- 時間複雜度:O(logn),對於每次迭代,我們會將輸入除以 10,因此時間複雜度爲 O(logn)。
- 空間複雜度:O(1)。我們只需要常數空間存放若干變量。