剑指offer--整数中1出现的次数

找规律问题:
分析1~任意数中各个位出现1的情况:
1~10:个位出现1的次数为 10^0;(只有1)
1~100:十位出现1的次数为10^1;(10,11,12,…,19)
1~1000: 百位出现1的次数为10^2;(100,101,…,199)

类推可得:
1~n的个位出现1的次数为 n/1010^0;
1~n的十位出现1的次数分为三种情况:
a:n的十位上数字为0:
此时1出现的总的次数为n/100
10^1;
举个例子,比如1~1200:十位上为1的只和它的高位(12)有关, 共有120个,(10,11,12,…,19,10,21,22,…29,…,1110,…,1119)
b:n的十位上数字为1:
此时我们还要加上除以100余数的部分+1:
即总次数为n/100*10^1+n%100+1;
举个例子,1~1219:
从上面可知11200是120个1,12011219中十位为1的数刚好就是(10,11,12,…,19)
c:n的十位上数大于1:
此时我们要加上固定的十个数(10^1),因为肯定会有(10,11,…,19)
举个例子,11222,11200,1200~1222中肯定会有(1210,1211,…1219)十个数,因此
总的个数为(n/100+1)*10^1
其他位的情况类似,都是三种情况。(当然发散成求任意数(0,2,3,4,5,6,7,8,9)出现的次数也是这三种情况)。【如果自己还总结不出规律的,就去看看《编程之美》】

#include <cmath>
class Solution {
public:
    int NumberOf1Between1AndN_Solution(int n)
    {
        if(n<1)
            return 0;
        int count = 0;//统计1出现的次数
        int flag = 1;//标记位,个位是1,十位是2...
        int num = n;//每次除以10来统计可以整除部分中1的次数
        while(num)
        {
            int tmp=num;
            int res = num % 10;
            num = num / 10;
            if(res == 0)
                count += num*pow(10,flag-1);
            else if(res>1)
                count += (num+1)*pow(10,flag-1);
            else
                count = count + num*pow(10,flag-1) + n-tmp*pow(10,flag-1) + 1;
            flag++;
        }
        return count;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断路器保护灵敏度校验整改及剩余电流监测试点应用站用交流系统断

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值