剑指offer()整数中1出现的次数(从1到n整数中1出现的次数)

本文介绍了一种高效算法,用于计算任意非负整数区间内数字1出现的总次数。通过分析个位、十位、百位等位上的1的数量,提出了针对不同情况的计算公式。并通过代码实现,展示了如何快速解决这一问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

求出1到13的整数中1出现的次数,并算出100到1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数)。

分析

设定1、10、100、1000…为中间点,分别考虑个位、十位、百位上…有多少个包含1的数进行分析。

根据设定的位置i(i=1、10、100…)对n进行分割,可以分为两部分,高位为a=n/i,低位为b=n%i。

当i=100时:

若百位对应的数字大于等于2,设n=71343,那么a=713,b=43。此时百位为1的次数有a/10+1=72次。72次中每次都包含0到99这100个连续的数,那么百位为1的数一共有72×100=7200次。也即 (a/10+1)×100

若百位对应的数为1,设n=13198,那么a=131,b=98。此时百位对应的数就是1,需要分两部分考虑:
(1)对于a/10=13次百位为1(0到12),每次都包含包含0到99个连续数,那么百位为1的数一共有13×100=1300次。也即a/10×100
(2)对于最高两位为13时,百位为1,此时百位为1所包含的数共有0到98个,即b+1个。
综上,百位对应的数为1时,百位为1的数共有a/10×100+b+1个。

若百位对应的数为0,设n=13066,那么a=130,b=66。那么百位为1的次数为0到12,13次,即a/10,每次均包含0到99个连续数,那么满足要求的数共有12×100=1200个。也即a/10×100

综合以上情况:
当百位对应的数为0或者大于等于2时,有(a+8)/10次包含0到99个连续数。之所以补8,是因为当百位为0,则a/10==(a+8)/10,当百位>=2,补8会产生进位位,效果等同于(a/10+1)。
当百位对应的数是1时,需要增加未满100的数b+1个。

代码

class Solution {
public:
    int NumberOf1Between1AndN_Solution(int n)
    {
    int count=0;
    long long i=1;
    for(i=1;i<=n;i*=10)
    {
        int a = n/i,b = n%i;
        count=count+(a+8)/10*i+(a%10==1)*(b+1);
    }
    return count;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值