面试题四十三:在1~n整数中1出现的次数

 

方法一:直观来看,遍历1到n,每个数去做%10的循环判断

  int Number1_B_1toN( int n){
                 int sum=0;
                 for(int i=1;i<=n;i++){
                     int k=i;
                     while(k!=0){
                           if(k%10==1)
                             sum++;
                           k/=10;          
                     }
                 }
                 return sum;
             }

方法二:无需遍历每一个数,只对最大的位数进行分解,就是当前位*高位的数字+当前低位数字范围中,当前位为1的数量

如 32629;当前为6,百位 。32*100+(0到629中百位为1的数量 =100)

对于 n = 2134,要找到从1 ~ 2134这2134个数字中所有1的个数。我们可以对2134进行逐位分析:
(1)在个位上,从1~2130,包含213个10,因此数字1出现了213次,剩下的数字2131、2132、2133、2134中个位数上只有2131包含树脂字1,剩下的都不包含。所以个位数上的数字1的总数为213 + 1 = 214
(2)在十位上,从1 ~ 2100,包含了21个100,因此数字1出现了21 * 10 = 210次,剩下的数字从2101 ~ 2134,只有2110 ~ 2119这10个数字中十位的数字为1,所以十位上的数字1的总数为210 + 10 = 220
(3)在百位上,从1 ~ 2000,包含了2个1000,因此数字1出现了2 * 100 = 200次,剩下的数字从2001 ~ 2134,只有2100 ~ 2134这35个数字中的百位的数字为1,所以百位数上数字1的总数为200 + 35= 235。
(4)在千位上,包含了0个10000,因此数字1出现了0 * 1000 = 0次,剩下的数字中只有1000 ~ 1999这1000个数字中的千位的数字为1,所以千位上的数字1的总数为1000。因此从1 ~ 2134这n个数字中,数字出现的总的次数为214 + 220 + 235 +1000 = 1669

 int NumberOfDigitOne(int n) {
        if( n < 0)
            return 0;
        int i = 1;  //从个位开始,10的1次方级别
        int high = n; //
        int cnt = 0;
        while(high != 0)
        {
            high = n / pow(10 ,i);//high表示当前位的高位 
            int temp = n / pow(10, i - 1);
            int cur = temp % 10;//cur表示第i位上的值,从1开始计算
            int low = n  - temp * pow(10, i - 1);//low表示当前位的低位
            if(cur < 1)
            {
                cnt += high * pow(10, i - 1);
             // 比如120;i=1;hight=12;那就就有12个10;每个10有1个1,就有12个,在加当前位0,0就达不到1;就12个
            }
            else if(cur > 1)
            {
                cnt += (high + 1) * pow(10 ,i - 1); 
               // 比如125;i=1;hight=12;那就就有12个10;每个10有1个1,就有12个,在加当前位5,1到5有一个1;就13个
            }
            else
            {
                cnt += high * pow(10, i - 1);
                cnt += (low + 1);
               // 比如120;i=1;hight=12;那就就有12个10;每个10有1个1,就有12个,在加当前位0,0就达不到1;就12个  
            }
            i++;
        }
        return cnt;
    }
    
    int pow(int k, int i2) {
         k=1;
              for(int i=1;i<=i2;i++)
                  k*=10;
     return k;
    }

 

posted @ 2020-03-29 16:33  浪波激泥  阅读(279)  评论(0编辑  收藏  举报