Leetcode OJ | Number of Digit One

先上题:
Given an integer n, count the total number of digit 1 appearing in all non-negative integers less than or equal to n.

For example:
Given n = 13,
Return 6, because digit 1 occurred in the following numbers: 1, 10, 11, 12, 13.
又是一个简单明了的题目。给定一个数n,要求找出从0开始的所有自然数中,1出现的次数。这里注意到11是有两个1的,也就是按位计数。

自然不可能用暴力检查的方法解决,考虑到这题具有一定的“取位”的技巧,除和取模运算自然少不了。但关键是,取什么位,怎么计算1的个数。

可以推导出,某一个位取1的可能性不仅和该位有关,还和这个位的前后有多少种数字的排列组合有关。比如某数十位是9,自然可以取到小于这个数的所有十位是1的数。还有一点,第k位如果能全部取到,那么该位的1的总数一定和10^k有关。

于是分三种情况:
(1)k位是0
那么,就只能取到前面的位组成的数乘以10^k。
(2)k位是1
那么,就必须取到前面的位组成的数乘以10^k在加上后面的位组成的数再加一。(因为从0到s的可能性是s+1种)。
(3)k位>1
那么,就取到前面的位组成的数加一乘以10^k。
公式:
if ( k == 0 )
result += (n/(10^k))*k;
if ( k == 1)
result += (n/(10^k))*k + n%10^(k-1) + 1;
if ( k > 1 )
result += (n/(10^k)+1) * k;
以下为代码:

class Solution {
public:
    int countDigitOne(int n) 
    {
        long long result = 0;
        int size = getnumber(n);
        long s = 1;
        int judge = 0;
        for(int i=0;i<size;++i)
        {
            judge = (n%(s*10))/s;
            if(judge > 1)
                result += (n/(s*10)+1)*s;
            else if (judge == 1)
                result += (n/(s*10))*s + n%s + 1;
            else result += (n/(s*10))*s;
            s*=10;
        }
        return result;
    }
    int getnumber(int n)
    {
        int bits = 0;
        while(n!=0)
        {
            n/=10;
            ++bits;
        }
        return bits;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值