Algorithm questions daily practice---Day 72: The number of number 1

Get into the habit of writing together! This is the 7th day of my participation in the "Nuggets Daily New Plan · April Update Challenge", click to view the details of the event .

1. Problem description

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

Topic link: The number of number 1

Second, the subject requirements

Example 1

输入: n = 13
输出: 6
复制代码

Example 2

输入: n = 0
输出: 0
复制代码

visit

1.数学思想、超时优化
2.建议用时15~35min
复制代码

3. Problem Analysis

As soon as I got my hands on this question, I felt that something was wrong. It was a very simple question that only needed to be counted in a loop. Likou actually added a difficult label to it.

class Solution {
public:
    int countDigitOne(int n) {
        int i,k,ans=0;//初始化数据
        for(i=1;i<=n;i++)//循环1~n
        {
            k=i;
            while(k)//数位中是否包含1
            {
                if(k%10==1)
                    ans++;//计数
                k=k/10;
            }
        }
        return ans;//输出结果
    }
};
复制代码

So, my code definitely times out.

1.png

17.png

After reading the solution >_<, I found that this is a regular question:

2.png

The rules are as follows, drawing on the ideas of the big guys:

/**
从低往高位,计算每一位的数量:
第1位上的1的个数:1+(n-1)/10
第2位上的1的个数:(1+(n/10-1)/10)*10
第3位上的1的个数:(1+(n/100-1)/10)*100
……
第k+1位上的1的个数:(1+(n/(10^k)-1)/10)*(10^k)
如果n的第k+1位上是1,则说明可能没有填满该位,计算第k+1位的数量时还要 -10^k+1+n%(10^k),相当于独立计算
 */
复制代码

Fourth, the encoding implementation

class Solution {
public:
    int countDigitOne(int n) {
        long long k = 1,ans = 0;//初始化数据
        while (n >= k){
            ans += (1+(n/k-1)/10)*k;//计数
            if (n/k%10 == 1) ans = ans-k+1+n%k;//当前位为1,减去数据
            k *= 10;
        }
        return ans;//输出结果
    }
};
复制代码

5. Test results

4.png

3.png

Guess you like

Origin juejin.im/post/7083646563754442783