Number of Digit One——LeetCode⑩

//原题链接https://leetcode.com/problems/number-of-digit-one/

  • 题目描述

    Given an integer n, count the total number of digit 1 appearing in all non-negative integers less than or equal to n.

    Example:

    Input: 13
    Output: 6 
    Explanation: Digit 1 occurred in the following numbers: 1, 10, 11, 12, 13.
    
  • 思路分析
    1.暴力法:对10求余,判断个位是否为1,然后除10依次判断//会超时
    2.优化:总结n每位数的规律,
    以n=123为例
       (1的个数:count
       当前位数上的权重:weight
       当前位数上的数字:now
       上一位数:last,例如按照从右到左,2的上一位数为3
       循环次数:round)
    个位数:3属于大于等于1,第十三个循环开始,则count = round + 1 = 12+1;
                  若为120,即now为小于1,开始第十三个循环,则count = round=12;
    十位数及以上位数:以十位数为例,2大于1,则count = round*weight + weight=1*10+10
                                                            若为11X,即now为1,则count = round*weight + 1+last=1*10+1+x
                                                            若为10X,即now等于0,则count=round*weight=1*10

         
  • 源码附录
     
    class Solution {
        public int countDigitOne(int n) {
            if(n<1){
                return 0;
            }
            
            int count = 1;
            for(int i=0;i<=n;i++){
                while(i>0){
                    if(i%10 == 1){
                        count ++;                       
                    }               
                    i = i / 10;
              }
            }
             return count;
        }
    }

     

    class Solution {
        public int countDigitOne(int n) {
            if(n<1){
                return 0;
            }
            
            int count = 0;
            int round = n;
            int weight = 1;
            int now = 0 ;
            while(round>0){
                now = round%10;
                round = round/10;
                if(now==1){
                    count = count + (n%weight)+1;
                }
                else if(now>1){
                    count = count + weight;
                }
                count = count + round*weight;
                weight = weight*10;
            }        
             return count;
        }
    }

     

<think>好的,我需要帮助用户编写一个Python函数CountDigit,用来统计整数中指定数字的出现次数。用户可能已经看过一些示例代码,包括用数学方法处理和字符串转换的方法。我需要结合这些引用中的信息,给出正确的实现方法。 首先,用户提供的引用里有三个不同的代码示例。引用[1]展示了三种不同的方法:第一种使用数学运算,处理负数时用了math.fabs;第二种类似,但没有用math库;第三种则是将数字转换为字符串,再统计字符出现次数。引用[2]和[3]是C语言的相关问题,但思路类似,比如处理负数和逐位检查数字。 用户的问题是如何用Python实现这个功能。我需要考虑不同方法的优缺点。数学方法可能更高效,而字符串转换方法更简洁。需要注意处理负数的情况,比如先将数字取绝对值。此外,digit的有效范围是0-9,但用户的问题中提到digit是0到9之间的数字,所以可能需要验证输入,不过题目可能假设输入正确。 接下来,我应该分步骤思考函数的编写: 1. 处理负数:无论输入是正还是负,都转换为正数处理,因为负号不影响数字的出现次数。 2. 处理number为0的情况,当digit是0时,返回1。 3. 方法一:数学运算。用循环取余数和整除来逐位检查。 4. 方法二:字符串转换。将数字转换为字符串,直接统计字符出现的次数。 5. 比较两种方法的优缺点,比如数学方法更高效,尤其是对于非常大的数字,但字符串方法更简洁易读。 需要测试边界情况,比如number为0,digit为0;number为负数且digit出现在其中;digit为0的情况等。 现在,根据引用中的代码,比如引用[1]中的第三种方法,将数字转换为字符串,这样实现起来最简单。例如,使用math.fabs处理负数,转换成字符串后,再统计字符出现次数。但要注意,digit需要转换为字符串,否则可能类型不匹配。例如,digit是整数,需要转换为字符来匹配字符串中的每个字符。 例如,函数可以这样写:将number的绝对值转为字符串,然后统计其中str(digit)的出现次数。这样就能正确处理负数和0的情况。 不过,对于number为0的情况,比如number是0,digit是0,应该返回1。这在字符串处理中会自动处理,因为字符串是"0",包含一个'0'字符。 另一种数学方法则是通过循环取余数,每次取出最后一位,比较是否为digit,然后去掉最后一位,直到number变为0。这种方法需要注意处理0的情况,比如当number已经是0时,循环不会执行,所以需要单独处理。 比如,当number是0,digit是0时,数学方法需要返回1。所以需要先检查number是否为0,如果是的话,直接比较digit是否为0,如果是,返回1,否则返回0。 现在,结合这些思考,我需要编写两种方法的示例代码,并说明它们的优缺点。 另外,用户的问题中要求函数名为CountDigit,参数为numberdigit。需要注意的是,digit应该在0-9之间,否则应该如何处理?可能题目假设输入合法,所以不需要额外检查。 最后,生成相关问题,可能需要围绕函数的实现方法、处理边界情况、性能比较等方面提问。</think>### 分步解答 以下是实现统计整数中指定数字出现次数的两种方法及详细说明: --- #### **方法一:数学逐位取余法** **核心思路**:通过循环取余数的方式逐位检查数字。 ```python import math def CountDigit(number, digit): if digit < 0 or digit > 9: return 0 # 确保digit是0-9的数字 number = int(math.fabs(number)) # 处理负数 count = 0 if number == 0 and digit == 0: # 单独处理0的情况 return 1 while number > 0: if number % 10 == digit: count += 1 number = number // 10 return count ``` **说明**: 1. 使用`math.fabs`确保`number`为正数。 2. 单独处理`number=0`且`digit=0`的情况(循环无法处理)。 3. 循环中取余数`number%10`获取最后一位,比较是否为`digit`。 4. 时间复杂度为$O(\log n)$,与数字的位数相关。 --- #### **方法二:字符串直接统计法** **核心思路**:将整数转换为字符串后直接统计目标字符。 ```python import math def CountDigit(number, digit): number_str = str(int(math.fabs(number))) # 转为正数字符串 return number_str.count(str(digit)) ``` **说明**: 1. 通过`str(math.fabs(number))`处理负数并转换为字符串。 2. 使用字符串方法`.count()`统计`digit`对应的字符。 3. 时间复杂度为$O(n)$,但代码更简洁,适合小规模数据。 --- ### **两种方法对比** | 方法 | 优点 | 缺点 | |------------|--------------------------|--------------------------| | 数学逐位法 | 高效,适合大整数 | 需处理边界条件(如0) | | 字符串法 | 代码简洁,无需循环 | 转换字符串可能略慢 | --- ### **测试示例** ```python print(CountDigit(-21252, 2)) # 输出3 print(CountDigit(0, 0)) # 输出1 print(CountDigit(10090, 0)) # 输出3 ``` --- ### 相关问题 1. 如何处理数字0的特殊情况?例如`number=0`且`digit=0`时如何统计? 2. 为什么在数学逐位法中需要单独处理`number=0`的情况? 3. 字符串法能否正确处理负数?例如`number=-123`时统计数字3? 4. 两种方法的时间复杂度分别是多少?哪种更高效? --- ### 引用说明 - 数学逐位法的思路参考了C语言实现中对负数的处理[^3]。 - 字符串法直接利用Python字符串操作简化逻辑[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值