[LeetCode][233]数字 1 的个数

题目

233. 数字 1 的个数

给定一个整数 n,计算所有小于等于 n 的非负整数中数字 1 出现的个数。

  • 示例 1:

输入:n = 13

输出:6

  • 示例 2:

输入:n = 0

输出:0

  • 提示:
    0 <= n <= 10^9

解法1:

  1. 这种题其实就是找规律,类似于数学归纳法,找出一个计算通式可以在给出任意值时计算到目标结果
  2. 这道题我选择从高位往低位统计
  3. 首先找规律,得出不同位数1出现的次数:0位0次,1位(0-9)1次,2位(0-99)20次...
  4. 然后从高位开始,例如123从高位开始,依次处理 100、20、3。
  5. 100包含了0-99,有20个1,20包含了12个1,3包含了1个1
  6. 而123后面的23又为百位上的1多加了24个1,即100-123百位上共24个1,这个也要统计

cpp 复制代码
class Solution {
public:
    int countDigitOne(int n) {
        if(!n) return 0;
        vector<int> count(10, 0);
        for(int i=1; i<=9; ++i){//统计不同位数的1出现的次数,0位0次,1位(0-9)1次,2位(0-99)20次...
            count[i]=i*pow(10, i-1);
        }
        // for(auto &ele:count) cout << ele << endl;

        int numDigits = (int)log10(n) + 1; // 获取数字的位数
        cout << numDigits << endl;
        int ans=0;
        for (int i = numDigits-1; i >= 0; i--) {//从高位开始统计
            int powerOf10 = (int)pow(10, i);
            int digit = n / powerOf10; // 获取当前位的数字
            if(digit==0) continue; //处理类似102这种情况中间的0

            ans+=digit*count[i];

            n %= powerOf10; // 移除当前位

            //如123,23让1多出现了24次(100-123),而423是百位上的1固定出现了100次(101-199)
            digit<=1 ? ans=ans+n+1 : ans+=powerOf10; 
        }

        return ans;
    }
};

解法2:

  1. 另一种解法是统计当前位上,1出现了多少次
  2. 当当前位上为0时,其出现1的次数由高位确定,如1203,十位上1出现的次数由十位以上确定,此处出现了12*10=120次
  3. 当当前位上为1时,其出现1的次数为高位+低位共同确定,如1213,出现了12*10+3+1=124次
  4. 当当前位上位2-9时,其出现1的次数也只由高位确定,如1243,十位上1出现次数为 (12+1)*10=130次

cpp 复制代码
class Solution {
public:
    int countDigitOne(int n) {
        long currentDigit = 1; // 当前位的权值,最低位开始
        int high = n / 10, cur = n % 10, low = 0, count = 0; // 初始化高位、当前位、低位、结果个数

        while (high != 0 || cur != 0) {
            if (cur == 0) {
                // 当前位为0时,结果由高位决定
                count += high * currentDigit;
            } else if (cur == 1) {
                // 当前位为1时,结果由高位和低位共同决定
                count += high * currentDigit + low + 1;
            } else {
                // 当前位大于1时,结果由高位决定
                count += (high + 1) * currentDigit;
            }

            // 更新低位并跳到下一位
            low += cur * currentDigit;
            cur = high % 10;
            high /= 10;
            currentDigit *= 10; // 更新位数权值
        }

        return count;
    }
};
相关推荐
ghie90906 分钟前
ART 和SART 医学CT重建迭代重建算法
人工智能·算法·计算机视觉
熊猫_豆豆8 分钟前
基于改进沙猫群优化算法的Otsu图像分割
人工智能·算法·计算机视觉
吃着火锅x唱着歌9 分钟前
LeetCode 624.数组列表中的最大距离
数据结构·算法·leetcode
im_AMBER13 分钟前
Leetcode 64 大小为 K 且平均值大于等于阈值的子数组数目
笔记·学习·算法·leetcode
AndrewHZ13 分钟前
【图像处理基石】什么是图像处理中的注意力机制?
图像处理·pytorch·深度学习·算法·计算机视觉·注意力机制·通道注意力
DuHz16 分钟前
通感一体化(ISAC)波形设计的实验验证研究——论文阅读
论文阅读·算法·信息与通信·毫米波雷达
CoderYanger16 分钟前
递归、搜索与回溯-综合练习:22.优美的排列
java·算法·leetcode·深度优先·1024程序员节
慕沐.31 分钟前
【算法】冒泡排序的原理及实现
java·算法·排序算法
TracyCoder12332 分钟前
分布式算法(八):一致性哈希——分布式系统的负载均衡利器
分布式·算法·哈希算法
roman_日积跬步-终至千里35 分钟前
【模式识别与机器学习(2)】主要算法与技术教程(上篇:基础分类算法)
算法·机器学习·分类