43. 1~n 整数中 1 出现的次数

剑指 Offer 43. 1~n 整数中 1 出现的次数

思路:数学

设数字n是个x位数,记n的第i位为 n i n_i ni,则可将n写为 n x n x − 1 ⋯ n 2 n 1 n_xn_{x-1}\cdots n_2 n_1 nxnx1n2n1;

  • n i n_i ni为当前位,记作cur
  • n i − 1 n i − 2 ⋯ n 2 n 1 n_{i-1}n_{i-2}\cdots n_2 n_1 ni1ni2n2n1为low
  • n x n x − 1 ⋯ n i + 2 n i + 1 n_xn_{x-1}\cdots n_{i+2}n_{i+1} nxnx1ni+2ni+1为high
  • 1 0 i 10^i 10i为因子,记为digit

根据当前位cur的不同,分为以下三种情况:

1.cur=0时:cur出现1的次数由高位high决定,计算公式为:

h i g h × d i g i t high\times digit high×digit

2.cur=1时:cur出现1的次数由high和low决定,计算公式为:

h i g h × d i g i t + l o w + 1 high\times digit+low+1 high×digit+low+1

3.cur=2,3,…9时:cur出现1的次数由高位high决定,计算公式为:

( h i g h + 1 ) × d i g i t (high+1)\times digit (high+1)×digit

class Solution {
public:
    int countDigitOne(int n) {
        int high=n/10,cur=n%10,low=0,res=0;
        long digit=1;
        while(high||cur){
            if(cur==0) res+=high*digit;
            else if(cur==1) res+=high*digit+low+1;
            else res+=(high+1)*digit;

            low+=digit*cur,cur=high%10,high/=10,digit*=10;
        }
        return res;
    }
};

时间复杂度 O(logn)

空间复杂度 O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值