剑指 Offer JZ31 整数中1出现的次数(从1到n整数中1出现的次数)

Posted 程序字母K

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指 Offer JZ31 整数中1出现的次数(从1到n整数中1出现的次数)相关的知识,希望对你有一定的参考价值。

输入一个整数 n ,求1~n这n个整数的十进制表示中1出现的次数
例如,1~13中包含1的数字有1、10、11、12、13因此共出现6次

在这里插入图片描述

范围1的个数
0-91==1
0-991*10+10==20
0-99920*10+100==300
0-9999300*10+1000==4000
0-999994000*10+10000==50000
…………

公式: 位数上数用n表示,e表示位数

10^e-1 * e

方法一:

自己发现规律,然后摸索公式;如上:

class Solution {
public:
    int NumberOf1Between1AndN_Solution(int n) {
        if(n<=0) return 0;
        int count=0;
        int ret=0;
        int temp=n;
        while(temp){//记录位数
            temp/=10;
            count++;
        }
       // pow(10,exponent-1)*exponent;
        int e=0;
        int a=0,b=n;
        while(count--){
            a=b%10;//a记录每一位的数,从最低位开始
            b=b/10;//b记录剩下的数,
            //个位含1数,写入。。十位含1数,写入..依次...
            if(a>1)
                //如果位数,为0,什么都不做,是1,就把前面+位数前面的数字大小再+1,
                //大于1,就直接用公式;
            ret+=pow(10,e-1)*e*a+pow(10,e);
            else if(a==0) {}
            else {
                int index=pow(10,e);
                ret+=pow(10,e-1)*e*a+n%index+1;
        }
                        e++;
        }
        return ret;

方法二:

网上的,公式也不太明白,仅供参考;

        
	int cnt = 0;
     for(int m = 1; m <= n; m *= 10) {
         int a = n / m, b = n % m;
         cnt += (a + 8) / 10 * m + (a % 10 == 1 ? b + 1 : 0);
     }
     return cnt;

方法三:

递归查找n-1中1的个数;

    int NumberOf1Between1AndN_Solution(int n) {
        if(n<=0) return 0;
    int num=0;
        int i=n;
       
        while(i){
            if(i%10==1)
                num++;
            i/=10;
        }
            num+=NumberOf1Between1AndN_Solution(n-1);
        return num;
        }

方法四:

将数字转为字符串,循环遍历查看字符串中‘1’的个数;

     int Count(string s){
         int num=0;
         for(auto &e:s){
             if(e=='1')
                num++;
        }
         return num;
     }
    int NumberOf1Between1AndN_Solution(int n) {
        int ret=0;
         for(int i=1;i<=n;i++){
             ret+=Count(to_string(i));
         }
         return ret;

方法五:

循环遍历每个数,拆分看每一位是否有1;

 int NumberOf1Between1AndN_Solution(int n) {
       if(n<=0) return 0;
   int ret=0;
   for(int i=1;i<=n;i++){//遍历每个数
       int temp=i;
       while(temp){//循环拆分判断个位是否有1,直到数为0;
           if(temp%10==1)
               ret++;
           temp/=10;
       }
   }
       return ret;

   }

以上是关于剑指 Offer JZ31 整数中1出现的次数(从1到n整数中1出现的次数)的主要内容,如果未能解决你的问题,请参考以下文章

《剑指offer》JZ31 ~ JZ40

《剑指offer》JZ31 ~ JZ40

剑指 Offer JZ31 整数中1出现的次数(从1到n整数中1出现的次数)

剑指offer(C++)-JZ53:数字在升序数组中出现的次数(算法-搜索算法)

剑指offer(C++)-JZ53:数字在升序数组中出现的次数(算法-搜索算法)

剑指offer(C++)-JZ53:数字在升序数组中出现的次数(算法-搜索算法)