【LeetCode】233. Number of Digit One 数字 1 的个数(Hard)(JAVA)

【LeetCode】233. Number of Digit One 数字 1 的个数(Hard)(JAVA)

题目地址: 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.

题目大意

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

解题方法

  1. 要求所有小于等于 n 的非负整数中数字 1 出现的个数,可以先计算所有小于 10^k 中非负整数中数字 1 出现的个数。
  2. 计算小于 10^k 中非负整数中数字 1 出现的个数:可以拆分为两个,1、 1开头的个数(小于10^(k - 1) 的数算作 0 开头的数),2、非1开头的个数
  3. 小于 10^k 中 1 开头的个数: 10^(k - 1) 个,这里 1 开头的数中,所有的开头的 1 的个数可以很快计算出来,10^(k - 1) 个
  4. 小于 10^k 中非 1 开头数要计算 1 的个数,就是计算 10^(k - 2) 里面的 1 的个数然后再乘以非 1 开头的数总共有 10 个
  5. 这样就可以通过递归计算出小于 10^k 中非负整数中数字 1 出现的个数
  6. 最后要计算 n,其实就是计算 n 后面的 0 的个数,然后看 n 首位的数字,分别计算就行了
class Solution {
    Map<Integer, Integer> map = new HashMap<>();
    public int countDigitOne(int n) {
        if (n <= 0) return 0;
        if (n < 10) return 1;
        long pro = 10;
        int count = 1;
        while (pro <= n) {
            pro *= 10;
            count++;
        }
        pro /= 10;
        count--;
        int high = (int) (n / pro);
        int res = (int) Math.min(n - pro + 1, pro);
        int pre = getNum(count);
        res += high * pre;
        res += countDigitOne((int) (n % pro));
        return res;
    }

    // < 10^n
    public int getNum(int n) {
        Integer temp = map.get(n);
        if (temp != null) return temp;
        if (n == 1) return 1;
        int pre = getNum(n - 1);
        int res = (int) Math.pow(10, n - 1) + pre * 10;
        map.put(n, res);
        return res;
    }
}

执行耗时:0 ms,击败了100.00% 的Java用户
内存消耗:35.2 MB,击败了71.77% 的Java用户

欢迎关注我的公众号,LeetCode 每日一题更新
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值