【刷穿 LeetCode】9. 迴文數(簡單)
技術標籤:刷穿 LeetCode字串演算法資料結構leetcodejava
題目描述
判斷一個整數是否是迴文數。迴文數是指正序(從左向右)和倒序(從右向左)讀都是一樣的整數。
示例 1:
輸入: 121
輸出: true
示例 2:
輸入: -121
輸出: false
解釋: 從左向右讀, 為 -121 。 從右向左讀, 為 121- 。因此它不是一個迴文數。
示例 3:
輸入: 10
輸出: false
解釋: 從右向左讀, 為 01 。因此它不是一個迴文數。
進階:
你能不將整數轉為字串來解決這個問題嗎?
字串解法
既然進階裡提到了不能用字串來解決,那麼三葉就提供一下吧。
class Solution {
public boolean isPalindrome(int x) {
String s = String.valueOf(x);
StringBuilder sb = new StringBuilder(s);
sb.reverse();
return sb.toString().equals(s);
}
}
時間複雜度:數字 n 的位數,數字大約有 log10(n) 位,翻轉操作要執行迴圈。複雜度為 O(log10(n))
空間複雜度:使用了字串作為儲存。複雜度為 O(log10(n))
非字串解法(完全翻轉)
原數值 x
的不超過 int 的表示範圍,但翻轉後的值會有溢位的風險,所以這裡使用 long
進行接收,最後對比兩者是否相等。
class Solution {
public boolean isPalindrome(int x) {
if (x < 0) return false;
long ans = 0;
int t = x;
while (x > 0) {
ans = ans * 10 + x % 10;
x /= 10;
}
return ans - t == 0;
}
}
時間複雜度:數字 n
的位數,數字大約有
log
10
n
\log{10}{n}
log10n 位。複雜度為
log
10
n
\log{10}{n}
log10n
空間複雜度: O ( 1 ) O(1) O(1)
非字串解法(部分翻轉)
如果在進階中增加一個我們熟悉的要求:環境中只能儲存得下 32 位的有符號整數。
那麼我們就連 long
也不能用了,這時候要充分利用「迴文」的特性:前半部分和後半部分(翻轉)相等。
這裡的前半部分和後半部分(翻轉)需要分情況討論:
-
迴文長度為奇數:迴文中心是一個獨立的數,即
忽略迴文中心後,前半部分 == 後半部分(翻轉)
。如 1234321 迴文串 -
迴文長度為偶數:迴文中心在中間兩個數中間,即
前半部分 == 後半部分(翻轉)
。如 123321
class Solution {
public boolean isPalindrome(int x) {
// 對於 負數 和 x0、x00、x000 格式的數,直接返回 flase
if (x < 0 || (x % 10 == 0 && x != 0)) return false;
int t = 0;
while (x > t) {
t = t * 10 + x % 10;
x /= 10;
}
// 迴文長度的兩種情況:直接比較 & 忽略中心點(t 的最後一位)進行比較
return x == t || x == t / 10;
}
}
時間複雜度:數字 n
的位數,數字大約有
log
10
n
\log{10}{n}
log10n 位。複雜度為
log
10
n
\log{10}{n}
log10n
空間複雜度: O ( 1 ) O(1) O(1)
最後
這是我們「刷穿 LeetCode」系列文章的第 No.9
篇,系列開始於 2021/01/01,截止於起始日 LeetCode 上共有 1916 道題目,部分是有鎖題,我們將先將所有不帶鎖的題目刷完。
在這個系列文章裡面,除了講解解題思路以外,還會盡可能給出最為簡潔的程式碼。如果涉及通解還會相應的程式碼模板。
由於 LeetCode 的題目隨著周賽 & 雙週賽不斷增加,為了方便我們統計進度,我們將按照系列起始時的總題數作為分母,完成的題目作為分子,進行進度計算。當前進度為 9/1916
。
為了方便各位同學能夠電腦上進行除錯和提交程式碼,我建立了相關的倉庫:Github 地址 & Gitee 地址。
在倉庫地址裡,你可以看到系列文章的題解連結、系列文章的相應程式碼、LeetCode 原題連結和一些其他的優選題解。
#演算法與資料結構
#LeetCode題解
#演算法面試