JS leetcode 加一 題解分析

壹 ❀ 引

今天是刷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;
};

註釋已經寫得很清楚了,這裏就很少解釋,並且這段代碼雖然看起來比較多,可是運行時間要遠遠低於第一種實現方法。

那麼關於這道題就說到這裏了,本文結束。

相關文章
相關標籤/搜索