leetCode EASY -Q66. Plus One === ![](https://s2.51cto.com/images/blog/202108/03/d41ce0d2323853fe7d9868daf22eac2f.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/format,webp) --- ###### tags: `leetCode`, `練習刷題`, `1984` <br> ## 題目 You are given a large integer represented as an integer array digits, where each digits[i] is the ith digit of the integer. The digits are ordered from most significant to least significant in left-to-right order. The large integer does not contain any leading 0's. Increment the large integer by one and return the resulting array of digits. Example 1: Input: digits = [1,2,3] Output: [1,2,4] Explanation: The array represents the integer 123. Incrementing by one gives 123 + 1 = 124. Thus, the result should be [1,2,4]. Example 2: Input: digits = [4,3,2,1] Output: [4,3,2,2] Explanation: The array represents the integer 4321. Incrementing by one gives 4321 + 1 = 4322. Thus, the result should be [4,3,2,2]. Example 3: Input: digits = [9] Output: [1,0] Explanation: The array represents the integer 9. Incrementing by one gives 9 + 1 = 10. Thus, the result should be [1,0]. ## 解題: 這裡看似簡單,其實有陷阱。 我有個方法可以只看目前這些input output去做的公式: ``` var plusOne = function(digits) { const total = digits.join(""); const totalNums = Number(total) + 1; return totalNums .toString() .split("") .map(digit => parseInt(digit, 10)); }; ``` 這個方法確實針對這三個例子是成功的,但當你遇到了 JS 數字安全限制,你就再也加不下去了。什麼是 JS的數字安全限制? ## JS的 數字整數限制 數字整數限制是 能夠精確表示的整數範圍,超出這個範圍的整數可能會失去精度,導致計算結果不正確。 JavaScript 使用 雙精度 64 位浮點數(IEEE 754 標準)來表示數值,這種數值表示方式的整數部分有 53 位的有效數字(52 位存儲數字,1 位隱式的整數位)。因此: 能夠準確表示的整數範圍是: ![image](https://hackmd.io/_uploads/BytgqaZEJg.png) 這個範圍內的整數被稱為「安全整數」,因為這些整數能夠被準確表示和操作,不會因浮點數精度問題而出錯。 JavaScript 提供了兩個常量來幫助我們檢查安全整數: ![image](https://hackmd.io/_uploads/H1JMcpWEJg.png) 超出這個範圍的整數(即「非安全整數」)在計算時可能會發生精度丟失,例如兩個看似不同的數可能被視為相等。 所以當Leetcode做最後演算的時候: digits = [6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5,5,4,3]; 那我們就會因為上面的公式而出錯。 ## 我的解法: ``` var plusOne = function(digits){ let carry =1; for(let i = digits.length -1 ; i >= 0; i--){ const sum = digits[i] + carry; digits[i] = sum % 10; carry = Math.floor(sum/10); if(carry === 0) break; } if(carry > 0) digits.unshift(carry); return digits; } ``` 這裡要說的幾個重點是: 1. for(let i = digits.length -1 ; i >= 0; i--) 是從最後面開始loop的 for 迴圈做法。 2. sum 是最後一個數字 +1 3. digits[i] 每一個都取 尾數,例如 10 取尾數就是 0 4. carry 則拿sum 的整數。 5. 如果還有 carry ,就新增到digits每個值最前面。 ## 別人的解法: ``` var plusOne = function(digits) { for(let i = digits.length-1; i >= 0; i-- ){ if(digits[i] === 9){ digits[i] = 0; } else { digits[i] += 1; return digits; } } digits.unshift(1) return digits; }; ``` 我覺得別人的解法挺直白的,也是我追求的。 ## 總結: 在這次我學習到 從最後的開始loop。 然後做的function 也要再三設想各種可能性。 希望大家也能從中學到什麼。 ![image alt](https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExYXg4Znc1MDNtYnZydXE0aDNxNmh0dnhscjU3YzhpcmJjaHVwMjJjaiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/fxe8v45NNXFd4jdaNI/giphy.gif)