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

一、题目:

输入一个整数 n ,求1~n这n个整数的十进制表示中1出现的次数。

例如,输入12,1~12这些整数中包含1 的数字有1、10、11和12,1一共出现了5次。

示例 1:
输入:n = 12
输出:5

示例 2:
输入:n = 13
输出:6

限制:1 <= n < 2^31

本题与主站 题目: 233. 数字 1 的个数 相同。

二、思路和代码:

思路一:
从1开始,将每个小于N的数都转换成字符形,统计这个字符中出现的1的数字,使用一个计数器累加起来,计数器就是最后的结果。
但是这个题标注困难,没这么简单,提交~ 超时~

//超出时间限制:
class Solution {
public:
 int countDigitOne(int n)
{
    int countr = 0;
    for (long long i = 1; i <= n; i++) {
        string str = to_string(i);//转换成字符形
        countr += count(str.begin(), str.end(), '1');//使用count统计下来‘1’
    }
    return countr;
}
};

思路二:
找规律:所有的数字的每一位都可以分为小于1(0)、等于1(1)、大于1;据此有:
image.png

class Solution {
public:
    int countDigitOne(int n) {
        long long sum = 0;
        long long base = 1;
        long long cur,a,b;
        while(base <=n ){
            b = n % base;
            a = n/base;
            cur = a%10;
            a /= 10;
            if(cur>1) sum += (a+1)*base;
            else if (cur==1) sum+=(a*base+b+1);
            else  sum +=a*base;
            base *=10;
        }
        return sum;
    }
};

ps:↑参考:香辣鸡排蛋包饭(一听就很好吃的样子)的python版本视频题解:
LeetCode刷题力扣题解 | 剑指Offer 43. 1~n 整数中 1 出现的次数 | 思路讲解及Python3代码实现
据此完成的cpp版本,阿婆主讲得特别好。
办法三:

class Solution {
public:
   int countDigitOne(int n){
    int count = 0;
    for (long long i = 1; i <= n; i *= 10) {
//(n/(i∗10))∗i 表示 (i*10) 位上 \text{'1'}’1’ 的个数+
//min(max((n mod (i*10))−i+1,0),i) 表示需要额外数的 (i*10)(i∗10) 位上 \text{'1'}’1’ 的个数
        count += (n / (i*10)) * i + min(max(n %  (i*10) - i + 1, 0LL), i);//0LL是一个longlong零。
    }
    return count;
}
};
//以11为例:循环2次:2+2:   只数个位:1:01、11、 指数十位1:10、11
//以111为例:循环3次:12+12+12
//......

结果:
在这里插入图片描述

怕什么真理无穷,进一步有进一步的欢喜!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

甜橙の学习笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值