Day37: 整数中1出现的次数(从1到n整数中1出现的次数)

291 阅读2分钟

知识点基础数学

描述

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

注意:11 这种情况算两次

数据范围: 1≤n≤30000 1≤n≤30000 

题源:整数中1出现的次数(从1到n整数中1出现的次数)_牛客题霸_牛客网 (nowcoder.com)

进阶:空间复杂度 O(1)  ,时间复杂度  O(lognn) 

示例1

输入:

13

复制

返回值:

6

复制

示例2

输入:

0

复制

返回值:

0

思路:挨个获取到每个数字,然后每个分位上判断1的数量,然后将所有数量进行相加(不推荐) 数字都是由位数组成,某一位上面是1的个数是一定的,因此我们可以根据这个来处理。

假设我们要计算百位上总共有多少1:首先100-199有100个1,而1100-1199又出现了100个1,于是我们知道了每过1000个数字就会出现100个百位上的1 用内层循环找出这个数字有多少个1;用的是把这个字符先转为String类型,然后用charAt();来取出该字符; 若为1,则ans++;

于是我们就可以得到计算公式每一位的计算公式:

具体做法:

  • step 1:准备一个基础变量,记录位数,从1开始,每轮循环扩大10倍。
  • step 2:从1开始,即个位开始,直到基础变量大于n,每次按照公式统计相应位置1的个数。
public class Solution {
    public int NumberOf1Between1AndN_Solution(int n) {
        int ans = 0;
        for (int i = 1; i <= n; i++) {
            String t = i + "";
            for (int j = 0; j < t.length(); j++) {
                ans = t.charAt(j) == '1' ? ans + 1 : ans;
            }
        }
        return ans;
    }
}
  • 时间复杂度:O(nlog10​n),外循环一共循环n次,内循环最大循环次数不会超过最大数字logn的位数
  • 空间复杂度:O(1),常数级变量,无额外辅助空间使用