今天是刷leetcode的第三天,根據推薦優先刷數據結構相關的卡片,先把數據結構知識體系創建起來,否則就是題目無從下手答案也看不懂的尷尬局面。那麼今天的題目是加一,老規矩,先記錄本身的解題思路,再分析優質答案。javascript
題目以下:java
給定一個由整數組成的非空數組所表示的非負整數,在該數的基礎上加一。git
最高位數字存放在數組的首位, 數組中每一個元素只存儲單個數字。面試
你能夠假設除了整數 0 以外,這個整數不會以零開頭。數組
示例 1:瀏覽器
輸入: [1,2,3] 輸出: [1,2,4] 解釋: 輸入數組表示數字 123。示例 2:安全
輸入: [4,3,2,1] 輸出: [4,3,2,2] 解釋: 輸入數組表示數字 4321。
那麼本文開始。數據結構
咱們先來分析題目,題目想表達的意思是給一個整數組成的非空數組,好比數字123裝在數組中就是[1,2,3],咱們得在123的基礎上加1,因此輸出得是[1,2,4]。注意,每一個元素只能是單個數字,因此不會存在[1,20,4]相似的狀況。測試
我首先想到的就是對數組進行倒序遍歷,好比看最後一位數字是否小於9,若是小於則直接把尾數加1,直接返回返回數組便可:code
if (arr[length - 1] < 9) { arr[length] += 1; return arr; };
那麼若是尾數是9,就得把尾數變成0,並將尾數前一位數字加1,可這樣就麻煩了,若是前面尾數恰好又是9怎麼辦,那豈不是變成了10,題目要求每一個數字只能有一位,因此像[9,9]加1就得變成[1,0,0]。
當我還在想還要怎麼處理時,忽然靈機一動,不對啊,數字計算進位的事情交給數字本身去作不就行了,我爲何要花心思管,直接將數組轉成數字,讓數字自增1,再還原成數組豈不妙哉!
因而我寫了以下代碼:
var plusOne = function (digits) { // 1.將數組切割成字符串 // 轉數字並加1 // 轉字符串並再次切割成數組 return (Number(digits.join("")) + 1).toString().split(""); };
拿官方給的兩個例子測試了下,沒問題,果斷提交,而後掛了....
具體掛在了[6, 1, 4, 5, 3, 9, 0, 1, 9, 5, 1, 8, 6, 7, 0, 5, 5, 4, 3]
這個例子,正確答案很明顯是[6, 1, 4, 5, 3, 9, 0, 1, 9, 5, 1, 8, 6, 7, 0, 5, 5, 4, 4]
,但個人代碼卻輸出了["6", "1", "4", "5", "3", "9", "0", "1", "9", "5", "1", "8", "6", "7", "0", "5", "0", "0", "0"]
,這我就蒙圈了。
通過一番百度,這才發現了Number能表示的正負安全範圍爲-253到253,而上述使用Number加1的數字爲6145390195186705544
,已經超過了有效範圍。
固然也不是沒有解決方案,經過ES10的BigInt來解決數字超出範圍失去精度問題,使用也比較簡單,在數組默認加個n
,通過修改:
var plusOne = function (digits) { // 借用BigInt解決數字超出範圍的問題 return (BigInt(digits.join('')) + 1n).toString().split(''); };
OK,這下經過了測試。
上文的思路雖然很棒,跳出了看到數組本能想到遍歷的固有思路,但致命缺陷是BigInt畢竟是ES10的東西,ES6都沒徹底獲得瀏覽器支持,更況且說10,玩意麪試遇到了這題被面試官也這麼說,那不GG。
因此我仍是沒能逃過最初的思路,讓數組倒序遍歷,並手動控制數字自增,好比[1,2]
變成[1,3]
,像[9,9]
咱們能夠先變成[0,0]
再塞個1進去,上代碼:
/** * @param {number[]} digits * @return {number[]} */ var plusOne = function (digits) { var last = digits.length - 1; while (last >= 0) { // 若是最後一位數小於9,那麼自增長1就能夠返回 if (digits[last] < 9) { digits[last] += 1; return digits; } else { //反之加1等於10,因此先把這一位設置成0 digits[last] = 0; }; last--; }; // 考慮到[9,9]的狀況,遍歷完就成了[0,0]了,因此得從頭部加個1進去 if (digits[0] == 0) { digits.unshift(1); }; return digits; };
註釋已經寫得很清楚了,這裏就很少解釋,並且這段代碼雖然看起來比較多,可是運行時間要遠遠低於第一種實現方法。
那麼關於這道題就說到這裏了,本文結束。