[LeetCode]Number of Digit One,解题报告

本文介绍了一种高效算法,用于计算指定整数范围内数字1出现的总次数。通过对给定数值进行位分解,利用数学规律快速得出结果。

题目

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, n]的区间中1出现的次数。

具体思路

在面试过程中如果被问到类似的题目,一定不要着急,因为这肯定是一道找规律的题目。最好的办法是在白纸上写一个差不多大的数,然后分析如何计算每一位1出现的次数。

以24071为例,如果我们想计算百位上1出现的次数,具体思路如下:

  1. 获取百位的高位为24,获取百位的低位为71,当前百位数字为0。
  2. 从高位出发来分析,百位出现的次数有:00100~00190,01100~01190,02100~02190,…,23100~23190。总共有(24*100)个1出现。

这是百位为0的情况,如果百位为1的时候,那除了上述的(24*100)个1之外,还包括:24100~24171,共(71 + 1)个1,即总共:24 * 100 + 71 + 1。

如果百位大于1例如为6的时候,那除了最开始的(24*100)个1之外,还包括了:24100~24199,共100个1,即总共:(24 + 1)*100。

总结规律

其实通过上面的分析,我们就可以归纳出一个规律如下。

要求第i位1出现的次数,并且i的高位数为highN,低位数为lowN,当前第i位的数字为cdigit,则当前i位1出现的次数分三种情况:

  1. cdigit == 0, count = highN * factor.
  2. cdigit == 1, count = highN * factor + lowN + 1.
  3. cdigit > 1, count = (highN + 1) * factor.

其中,factor为当前的乘积因子,例如百位的factor为100,十位的乘积因子为10。

有了规律,代码只要按照规律写出来即可。


AC代码

public class NumberofDigitOne {
    public int countDigitOne(int n) {
        int count = 0;
        long factor = 1;
        long cdigit = 0;
        long highN = 0;
        int lowN = 0;

        while (n / factor > 0) {
            cdigit = (n % (factor * 10)) / factor;
            highN = n / (factor * 10);

            if (cdigit == 0) {
                count += highN * factor;
            } else if (cdigit == 1) {
                count += highN * factor + lowN + 1;
            } else {
                count += (highN + 1) * factor;
            }

            lowN += cdigit * factor;
            factor *= 10;
        }


        return count;
    }

    public static void main(String[] args) {
        int n = 1410065408;
        NumberofDigitOne ndo = new NumberofDigitOne();
        int count = ndo.countDigitOne(n);

        System.out.println(count);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

低调小一

您的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值