Leetcode-233-Number of Digit One

数数字的题目说难也难,说简单也简单,难就难在不重不漏,简单就简单在方法找对了,就是一个公式的事儿。

这道题的思路其实不难找,我们考虑一下什么时候会出现数字1:

1、11、21、……、91
10、11、12、……、19
100、101、……、199

我们看到,统计1在各个数位上出现的次数比较简单,不会重复也不易遗漏。我们看到11在这里出现了两次,按照数位计算的话就是十位计算一次个位计算一次,并不会产生重复。

现在的问题就是,如何计算各个数位上1的个数。

比如我们看数字142857,个位上有多少个1呢?把142857分成142857两部分,可以看到,前一部分可以取00000\sim14285,后一部分可以取1(<7),于是个位上1的个数就是14285+1=14286

下面我们看十位,同样的思路,我们把142857分成142857两部分,前一部分可以取0000\sim1428,后一部分可以取10\sim19(<57)于是十位上是1的个数为(1428+1)\times 10=14290

依次进行下去并将结果相加即为最终结果。

需要注意的特殊情况是某一位上的数字为01的情况,比如142807,我们在考查十位上数字1的个数的时候应该取1428(而非1429)\times10,因为07<10

当数字为142817,十位上数字1的个数为1428\times10+(17\% 10+1)

从而我们可以由以上规律得到一个统一的计算公式,代码如下:

class Solution {
public:
    int countDigitOne(int n) 
    {
        int res = 0;
        for (long i=1;i<=n;i*=10) 
            res+=(n/i+8)/10*i+(n/i%10==1)*(n%i+1);
        return res;
    }
};
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容