題目
給出一個 32 位的有符號整數,你需要將這個整數中每位上的數字進行反轉。
示例 1:
輸入: 123
輸出: 321
示例 2:
輸入: -123
輸出: -321
示例 3:
輸入: 120
輸出: 21
注意:
假設我們的環境只能存儲得下 32 位的有符號整數,則其數值範圍爲 [−2^31, 2^31 − 1]。請根據這個假設,如果反轉後整數溢出那麼就返回 0。
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/reverse-integer
解題思路
解決改問題主要關注兩個點:
- 整數反轉
- 判斷反轉後的整數是否還在32位有符號整數範圍之內
整數反轉:
就是一個小學公式做循環迭代,目的是分解出整數的各十百千等位的數字。所以這道題和迴文數的判斷、水仙花數都類似。
我的第一思路就是循環分解出整數的個十百千…的數字,一次加入集合中,然後再循環集合,分別取出數值乘相應權重,並計算總和,就得到反轉後的結果。
比如:待反轉的整數是123,將3,2,1分別存入集合,得到[3,2,1],然後遍歷集合,計算,得到321。權重100,10…如何得到的呢?就是根據集合的大小確定,初始權重是10的size-1次冪,遍歷一次指數減一。實現代碼如下:
//1.將整數的字符提取出來
int quotient;
//餘數
int remainder;
List<Integer> remainders= new ArrayList<>();
do {
quotient = x / 10;
remainder = x % 10;
x = quotient;
remainders.add(remainder);
} while (quotient > 0);
int size = remainders.size();
for(int i : remainders){
size =size-1;
result = result+ i*pow(size);
}
指數運算方法
public static int pow(int x) {
int result =1;
for(int i = 0;i<x;i++){
result = result*10;
}
return result;
}
在用代碼實現自己的思路過程中,我就覺得很不對勁,雖然寫完也能跑出正確結果,但是從空間複雜度和時間複雜度來說都不合格,多開闢了一個集合的空間,加了一個雙層循環,這完全是沒有必要的計算,這代碼寫的真的很蠢。其實在循環分解數字時就可以累乘和相加,代碼非常簡單。
判斷的整數範圍:
剛開始是想用Java的異常機制捕獲整形溢出出錯,結果發現並不會報錯。所以後面就只能用long類型定義result,然後判斷是否超出int類型。
正好Java的int類型就是帶符號的,佔用4個字節也就是32位。
代碼實現
public int reverse(int x) {
//int的最大值最小值
int max = Integer.MAX_VALUE;
int min = Integer.MIN_VALUE;
//int max = 0x7fffffff, min = 0x80000000;
long result = 0;
while (x != 0) {
result = result * 10 + x % 10;
x = x/ 10;
}
if (result > max || result < min) {
return 0;
} else {
return (int) result;
}
}
總結
這是一道簡單題,由於自己想的過於複雜,再饒了不少彎路之後雖然,但是代碼臃腫,而且效率很低。對於算法的學習只能多學習,多思考,多借鑑,多總結。也要記錄、反思自己的思考過程。