題目連接: leetcode-cn.com/problems/re…git
看到整數反轉這個題,最早聯想到先對數值取絕對值,而後除十取餘以對整數進行反轉,以後再考慮是否須要取負數以及數值範圍問題。github
/** * @param {number} x * @return {number} */
var reverse = function(x) {
let result = 0;
let value = Math.abs(x);
while (value !== 0) {
result = result * 10 + value % 10;
value = Math.floor(value / 10);
}
result = x > 0 ? result : - result;
return (result > Math.pow(2,31) - 1 || result < - Math.pow(2,31) ? 0 : result);
};
複製代碼
寫到這,本覺得就完成了,測試用例也都經過了。可是!你回想一下題目中的說明:微信
假設咱們的環境只能存儲得下 32 位的有符號整數。學習
咱們測試上面程序的時候並不是在這麼苛刻的環境下,因此先獲得 result
,再判斷其是否在所要求的數值範圍內,不在則 return (0)
,因此也正常經過了全部的測試用例。可是當真正在一個只能存儲得下 32 位的有符號整數的環境中,若是整數反轉後的數值超過要求的數值範圍,那咱們根本得不到 result
,由於會直接溢出。所以須要在整數反轉的時候就加上溢出判斷。測試
x
的每一位拆開,在進行整數反轉時,每一步都判斷是否溢出;MAX_VALUE
,另外一個是小於整數最小值 MIN_VALUE
,設當前計算結果爲 result
,下一位爲 pop
;result * 10 + pop > MAX_VALUE
這個溢出條件來看:
result > MAX_VALUE / 10
且還有 pop
須要添加時,則必定溢出;result === MAX_VALUE / 10
且 pop > 7
時,則必定溢出,7 是 2^31 - 1 的個位數(2^31 - 1 = 2147483647)。result * 10 + pop < MIN_VALUE
這個溢出條件來看:
result < MIN_VALUE / 10
且還有 pop
須要添加 時,則必定溢出;result === MIN_VALUE / 10
且 pop < -8
時,則必定溢出,8 是 -2^31 的個位數(-2^31 = -2147483648)。/** * @param {number} x * @return {number} */
var reverse = function(x) {
let result = 0;
let value = Math.abs(x);
let MIN_VALUE = - Math.pow(2,31);
let MAX_VALUE = Math.pow(2,31) - 1;
while (value !== 0) {
let pop = value % 10;
// 溢出判斷
if (result > MAX_VALUE / 10 || (result === MAX_VALUE / 10) && pop > 7) return 0;
if (result < MIN_VALUE / 10 || (result === MIN_VALUE && pop < -8)) return 0;
result = result * 10 + pop;
value = Math.floor(value / 10);
}
return (x >= 0 ? result : - result);
};
複製代碼
可使用 JavaScript 的字符串轉換方法,但字符串轉換的效率較低且依賴 API,在 leetcode.com 上測試發現,所耗時間和內存均要大於方法一。ui
還有一個嚴重的問題就是,經過字符串轉換後乘以係數這一步驟 let ret = coefficient * str.split('').reverse().join('');
,若是轉換後獲得的數值超出了題目要求的範圍,那這一步就已經溢出了,因此這種方法不適用。若是你有更好的方法,十分但願與你交流學習。spa
/** * @param {number} x * @return {number} */
var reverse = function(x) {
let coefficient = x >= 0 ? 1 : -1;
let str = Math.abs(x) + '';
let ret = coefficient * str.split('').reverse().join('');
return (ret > Math.pow(2, 31) -1 || ret < - Math.pow(2, 31) ? 0 : ret);
};
複製代碼
不知此處方法二的時間複雜度和空間複雜度如何計算,望獲得大佬的指導。code
請關注:github.com/leviding/le…cdn
本人水平有限,歡迎交流分享你的想法,歡迎大佬批評指正。blog
掃描下方二維碼,關注微信公衆號「技術漫談」,訂閱更多精彩內容。