動態規劃問題(五)數字1的個數
阿新 • • 發佈:2021-08-13
動態規劃問題(五)數字1的個數
問題描述
給你一個整數 n,計算所有小於等於 n 的非負整數中數字 1 出現的個數。
例如:對於整數 13,所有包含 1 的非負整數為 13、12、11、10、1 這些數裡面數字 1 總共出現了 6 次,因此得到的結果為 6.
解決思路
按照分位數計算 1 出現的次數即可。比如說,對於 13,我們可以首先計算個位數 1 出現的次數,再統計十位數上的出現次數即可。
一般來講,對於任意的一個整數 n,從個位開始依次計算每個位數 1 出現的次數,最終累加即可。
比如說,對於百分位來講(如果 n 此時大於 100),那麼當前就會有 $\lfloor \frac {n}{1000} \rfloor$ 個百分位的 1 出現,因此此時就會有 $\lfloor \frac {n}{1000} \rfloor \times 100$ 個 1 出現(因為 100 本身自帶一個 1,因此對於任意的 100,101 .....) 都至少會有一個 1。而對於餘數部分,此時要分三種情況:
- 餘數 < 100,那麼這種情況下在百分位的 1 就是 0,不要再考慮
- 100 <= 餘數 < 200,此時只有
餘數 - 100 + 1
個百分位的 1,+ 1 是由於要包括 100 - 餘數 >= 200,此時就會包含整個百分位的 1,因此這種情況下 1 的個數為 100
因此,對於當前n,再當前的百分位上包含的 1 的個數為:
$\lfloor \frac {n}{1000} \rfloor \times 100 + min(max(n \mod 1000 - 100 + 1, 0), 100)$
對於一般的位數:
$\lfloor \frac {n}{10^{k+1}} \rfloor \times 10^k + min(max(n \mod 10^{k + 1} - 10^k + 1, 0), 10^k)$
依次遍歷每個位數即可得到最終的結果。
實現
public class Solution { public static int countDigitOne(int n) { int ans = 0; // 初始計算個位數的 1 int digit = 1; // 不斷迭代每個位數的 1,即可得到最終的結果 while (digit <= n) { ans += (n / (digit * 10)) * digit + Math.min(Math.max(n % (digit * 10) - digit + 1, 0), digit); digit *= 10; } return ans; } }