Hi 你們好,我是張小豬。歡迎來到『寶寶也能看懂』系列之 leetcode 周賽題解。git
這裏是第 171 期的第 1 題,也是題目列表中的第 1317 題 -- 『將整數轉換爲兩個無零整數的和』github
「無零整數」是十進制表示中 不含任何 0 的正整數。shell
給你一個整數 n,請你返回一個 由兩個整數組成的列表 [A, B]
,知足:segmentfault
A
和 B
都是無零整數A + B = n
題目數據保證至少有一個有效的解決方案。數組
若是存在多個有效解決方案,你能夠返回其中任意一個。緩存
示例 1:安全
輸入:n = 2 輸出:[1,1] 解釋:A = 1, B = 1. A + B = n 而且 A 和 B 的十進制表示形式都不包含任何 0 。
示例 2:測試
輸入:n = 11 輸出:[2,9]
示例 3:優化
輸入:n = 10000 輸出:[1,9999]
示例 4:spa
輸入:n = 69 輸出:[1,68]
示例 5:
輸入:n = 1010 輸出:[11,999]
提示:
2 <= n <= 10^4
EASY
題目的要求爲,給定一個整數,須要返回把它看成和的一對不包含 0 的整數加數。
讀完題目後,個人第一反應是,是否是有什麼數學方法能夠找到答案。摸摸豬鼻子,想了一會,沒想到什麼靠譜的方法。必定是小豬太苯了,藍瘦 T_T
接下來把思路轉向了偏計算機的方式。那麼第一反應就是,暴力枚舉。時間複雜度 O(n),應該能 AC,那就先試試吧。
這種思路其實很是直接,就是遍歷一邊全部可能的加數,而後判斷它們是否包含 0 便可。因爲題目對於返回的解沒有要求,因此咱們直接返回第一組遇到的解便可。具體流程以下:
不過這裏能夠作一點小小的優化。一方面是,在判斷 0 的過程當中,咱們在除以 10 以後的取整操做能夠直接用位運算實現。另外一方面是,對於每個整數,它是否包含 0 是一個客觀的事實。因此咱們能夠針對全部的測試用例進行全局的緩存,避免沒必要要的計算。而且因爲題目限制了範圍是 [2, 10^4]
,因此咱們能夠用一個固定長度的數組來進行記錄。
具體代碼以下:
const memo = new Uint8Array(10000); const helper = x => { if (memo[x] !== 0) return memo[x] === 1; while (x > 0) { if (x % 10 === 0) { memo[x] = 2; return false; } x = x / 10 << 0; } memo[x] = 1; return true; }; const getNoZeroIntegers = n => { let m = 0; while (n--) { if (helper(++m) && helper(n)) return [m, n]; } };
熟悉小豬的小夥伴可能會猜到,若是隻給一個 brute force 方案,小豬必定不會知足噠 >.<
因而在一番絞盡腦汁以後,小豬決定先去玩幾盤吃雞, 小豬把思路重新放回了題目條件自己。若是想把一個整數變成一個不包含 0 的整數,那麼可能有兩種狀況。第一種,這個數自己就不包含 0,那麼咱們祝它新年快樂。第二種,其中某一位數字是 0,對於這種狀況,咱們詳細分析一下。
首先,這個 0 不多是最高位,由於題目給定的是普通的整數。那麼咱們若是想要把它變成別的數字的話,要麼是增,要麼是減。因爲咱們是在尋找加數,因此只能選擇減。而且因爲不是先導 0,因此減是安全的。減的數值基於當前位置來肯定,例如百位的話就減 100,十位的話就減 10。這樣咱們就把當前位置的 0 替換成了非 0。
不過這裏須要注意的是,咱們的一對加數都須要進行同步的加減運算,而且都須要反覆進行是否包含 0 的驗證。具體流程以下:
n - 1
做爲初始值。判斷它們是否包含 0:
基於這個流程,咱們能夠實現相似這樣的代碼:
const helper = x => { let digit = 0; while (x > 0) { if (x % 10 === 0) break; x = x / 10 << 0; ++digit; } return 10 ** digit; }; const getNoZeroIntegers = n => { let x = 1, y = n - 1; while (true) { let num = helper(y); if (num < y) { y -= num; x += num; continue; } num = helper(x); if (num > x) break; y -= num; x += num; } return [x, y]; };
這段代碼暫時 beats 100%。
周賽第一題,慣例送保底分。不過這道題我以爲用枚舉的方式已經 OK 了,後面提供的非枚舉的思路只是供小夥伴們娛樂一下。由於雖然不知道爲何,不過我總以爲這樣去處理問題有點怪怪的。
嘛,可能有不少小夥伴已經回家啦,或者被堵在了回家的路上。這裏仍是提早送上小豬誠摯的祝福,但願你們在新的一年裏,髮際線必定要平安哦。麼麼噠 >.<