1. 程式人生 > 其它 >1~n 整數中 1 出現的次數

1~n 整數中 1 出現的次數

技術標籤:leetcodejava

一、原題

題目:
輸入一個整數 n ,求1~n這n個整數的十進位制表示中1出現的次數。
例如,輸入12,1~12這些整數中包含1 的數字有1、10、11和12,1一共出現了5次。

示例 1:
輸入:n = 12
輸出:5

示例 2:
輸入:n = 13
輸出:6

二、思路

將每一位中出現的1相加
Case1:個位出現1的次數
個位出現1的次數主要取決於比它高的位,如987,這個位出現的次數應該為98次,因為每0~9一輪會初選一次1。
但是這又要考慮個位是否為0,如果個位為0,如980,則只出現97次。

Case2:其他位出現1的次數
以統計十位數出現1的次數為例。同樣的,如果不考慮個位數,十位數出現的次數取決於比它高的位,如987,則十位數出現1的次數為9次;當十位為0時,如907,則出現次數為8次。

但是另一個問題是,每次十位上出現1,由於個位還是會變化的,如910~919,則對應了十個數字。如果最後一個數為x1x,則最後一次出現1的個數取決於最後的個位數。

總結:
一個數字可以看做是 高位+當前位+低位
在這裡插入圖片描述

round=輪數(由高位決定)
weight=當前位數值(當前位為帶判斷的值)
base=對應的位數,(1,10,100…)
dig = 考慮個位數時,可能出現的次數(由低位決定)

總的來說可以分為三種情況:
(1)當前位為0:如3028
base = 100
round = n/(base10) (01xx,11xx,21xx)
出現的總次數為base
round
(2)當前位為1:
當最高位不是1時,如23128

base=100
round = n/(base10)+1 (001xx, 011xx, 021xx,031xx,041xx…121xx,231xx)
dig = n%base
出現的總次數為:base
(round-1)+dig+1

當最高位是1時:如128
base=100
出現的總次數為dig+1

(3)當前位>1:如13428

base=100
round=n/(base10)+1
出現的總次數為:base
round

三、程式碼

class Solution {
    public int countDigitOne(int n) {
        //1在個位+1在十位+1在百位,,,,以此類推
        int
total = 0; int weight = 0;//當前位的值 int round = 0;//由高位決定 int base = 1;//對應的位數,1,10,100等 int dig = 0;//儲存低位數字 while(n/base > 0){//說明此位上有數值 weight = (n/base)%10; if(weight == 0){ //如果這一位為0 round = n/(base*10); total += base*round; }else if (weight == 1){ dig = n%base; if(n/base == 1){ total += dig+1; }else{ round = n/(base*10)+1; total += base*(round-1) + dig + 1; } }else{ round = n/(base*10)+1; total += round * base; } if(base == 1000000000){//10^9次方是int中最大的10倍數,10次方就超出範圍了 break; } base *= 10; } return total; } }