【剑指 Offer】43. 1~n 整数中 1 出现的次数(详细解析)

本文介绍了一种计算1到n范围内所有整数中数字1出现次数的方法。通过数学分析和动态规划思想,文章提供了一个高效的算法实现,并附带详细代码解释。

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

第 60 日:1~n 整数中 1 出现的次数

题目链接:https://leetcode-cn.com/problems/1nzheng-shu-zhong-1chu-xian-de-ci-shu-lcof/

题目

image-20211213225215840

解题

  1. 数学、动态规划

    解题思路:
    要求计算1~n出现1的次数,也就相当于求数字n中每一位为1时可以出现的可能性。

    例如 :n=12  
    结果为: 5
    ##计算思路如下:
    当个位为1时  有 01、11
    当十位为1时  有 10、11、12 
    ##了解了上边计算思路就可以开始伪代码演示了:
    1.首先设置3个变量l、cur、r分别代表左高位、当前位、右低位
    	以12举例就是,l=1,cur=2,r=0;当前位标志digit为1(后面会10、100、1000...)
    2.当前位结果等于res=l*digit+digit=1*1+1=2
    3.计算十位的结果等于res=l*digit+r+1=0*10+2+1=3
    4.将res累加就是最后的结果
    

    这里要注意的是要根据当前位的值,选择计算res的方法:
    在这里插入图片描述
    上图来自男神K神

    详细代码如下:

        public int countDigitOne(int n) {
            int l=n/10,cur=n%10,r=0;//l代表高位   cur代表当前一位  r代表低位
            int digit=1;//当前位10 100 100...
            int res=0;//结果
            while(cur!=0 || l!=0){
                if (cur==0){
                    res+=l*digit;
                }else if (cur==1){
                    res+=l*digit+r+1;
                }else if (cur>1){
                    res+=l*digit+digit;
                }
                //低位左进
                r=cur*digit+r;
                //当前位左移
                cur=l%10;
                //高位左进
                l=l/10;
                //当前位数变化
                digit*=10;
            }
            return res;
        }
    

image-20211213225156820

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值