剑指offer 面试题43. 1~n整数中1出现的次数

leetcode上也见过一样的题,当时不会做 看了一下解法是纯数学解法就没看,结果剑指offer上也出现了这道题,那还是认真看下吧

对于数字abcde,如果第一位是1,比如12345,即计算f(12345)。
那么首位为1对结果的增益一共是10000到12345一共2346个。
另外首位为1的数字,后四位还可能有1出现,这部分即0001到2345(对应的数字就是10001到12345),也递归解决 f(2345)。
还有10000以下的数字(即4位数),这部分交给递归解决f(9999)。

如果第一位不是1,比如34567,即计算f(34567),另high为首位数字,此例high=3
那么首位为1对结果的增益是10000到19999一共10000个。
0001到9999的1出现的次数为x,即f(9999)为x,则10001到19999中1出现的次数(不包含第一位的1)是x,20001到29999中1出现的次数也是x。
所以这部分计算为high*f(9999)。
还有一部分在上一种情况也有,就是30000到34567中1出现的次数,为f(4567)。

class Solution {
public:
    int NumberOf1Between1AndN_Solution(int n)
    {
        if(n<1){return 0;}
        string s=to_string(n);
        int high=s[0]-'0';
        int p=int(pow(10,s.size()-1));
        s.erase(0,1);
        int low=atoi(s.c_str());
        if(high==1){
            return (low+1)+NumberOf1Between1AndN_Solution(low)+NumberOf1Between1AndN_Solution(p-1);
        }
        else{//high>1
            return p+high*NumberOf1Between1AndN_Solution(p-1)+NumberOf1Between1AndN_Solution(low);
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值