欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[算法] 从1到n整数中1出现的次数

程序员文章站 2024-03-15 17:06:54
...

从1到n整数中1出现的次数

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

题目描述:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。例如输入12,从1到12这些整数中包含1的数字有1,10,11和12,1一共出现了5次。

基本思路:从1到n遍历,得到一个数字中1出现的次数,然后累加,得到最终结果。

class Solution {
public:
    int NumberOf1Between1AndN_Solution(int n)
    {
        int result = 0;
        
        for(int i = 1; i <= n; i++){
            result += NumberOf1(i);
        }
        
        return result;
    }
    
    int NumberOf1(int n){
        int result = 0;
        
        while(n){
            if(n % 10 == 1){
                result++;
            }
            n /= 10;
        }
        
        return result;
    }
};

上面算法,数字n有O(logn)位,要循环判断n个数字,时间复杂度为O(nlogn).希望不用计算每一个数字中包含1的个数,而是寻找1出现的规律。
分析每个数位上出现1的情况,比如分析百位上为1, i = 100:

  • 百位上大于1,比如 n = 21245, 高位 a = n / i = 212,低位 b = n % i = 45
    百位为1的情况为 001 ** ~ 211**共22种,其中**为00 ~ 99共100个,因此为(a / 10 + 1) * i
  • 百位上等于1,比如 n = 21145, 高位 a = n / i = 211,低位 b = n % i = 45
    百位为1的情况为 001** ~ 201**共21种,其中**为00 ~ 99共100个,还有21100~21145共46个,因此为 ( a / 10 )* i + ( b + 1)
  • 百位上等于0,比如 n = 21045, 高位 a = n / i = 211,低位 b = n % i = 45
    百位为1的情况为 001** ~ 201**共21种,其中**为00 ~ 99共100个,因此为 ( a / 10 )* i

数位上为0,1时,为 a / 10;数位上大于1时,为 a / 10 + 1.
可以总结为( a + 8 ) / 10 * i + ( a % 10 == 1) * ( b + 1).

class Solution {
public:
    int NumberOf1Between1AndN_Solution(int n)
    {
        int result = 0;
        
        for(int i = 1; i <= n; i *= 10){
            int a = n / i;
            int b = n % i;
            result += (a + 8) / 10 * i + (a % 10 == 1) * (b + 1);
        }
        
        return result;
    }
};

拓展:从1到n整数中2出现的次数

程序员面试金典:2的个数

题目描述:给定一个正整数n,请返回0到n的数字中2出现了几次。

基本思路:同“从1到n整数中1出现的次数”

class Count2 {
public:
    int countNumberOf2s(int n) {
        // write code here
        int result = 0;
        
        for(int i = 1; i <= n; i *= 10){
            int a = n / i;
            int b = n % i;
            result += (a + 7) / 10 * i + (a % 10 == 2) * (b + 1);
        }
        
        return result;
    }
};