剑指Offer31:整数中1出现的次数(从1到n整数中1出现的次数)(Java)

参考牛客解答作者nailperry的总结:

原回答链接:https://www.nowcoder.com/questionTerminal/bd7f978302044eee894445e244c7eee6?f=discussion

解题思路:整数n出现1的次数=个位上1出现的次数+十位出现1的次数+百位出现1的次数+...+最高位1出现的次数
求出各位出现1的次数累加即结果。

首先要知道以下的规律:
每10个数个位出现1次1.
每100个数十位出现10次1.
每1000个数百位出现100次1.
...

个位出现1的次数:若n的个位是0则等于\(n/10\ast1\),若n的个位不是0则等于\(n/10\ast1+1\)
十位出现1的次数:若n的十位是0则等于\(n/100\ast10\),若n的十位是1则等于\(n/100\ast10+n%10\),若n的十位大于1则等于\((n/100+1)\ast10\)
百位出现1的次数:若n的百位是0则等于\(n/1000\ast100\),若n的百位是1则等于\(n/1000\ast100+n%100\),若n的百位大于1则等于\((n/1000+1)\ast100\)
...

得出计算第i位出现1的次数的规律:

  1. 取第i位左边(高位)的数字,乘以\(10^{i-1}\)基础值a
  2. 取第i位数字,计算修正值
    1. 如果大于1,则结果为a+\(10^{i-1}\)
    2. 如果等于1, 取第i位右边(低位)数字,设为b,则结果为a+b+1。
    3. 如果小于1,则结果为a。

题目描述:

求出113的整数中1出现的次数,并算出1001300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1到n中1出现的次数)。

代码:

public class Solution {
    public int NumberOf1Between1AndN_Solution(int n) {
        if(n<1)return 0;
        if(n>=1&&n<10) return 1;
        int high,curr,low,temp;//high是第i左边的高位。curr是第i位。 
        int i=1;               //low是第i位的低位。 temp是临时值
        int total=0;
        high=n/10;
        while(high!=0){
            high=n/(int)Math.pow(10,i);
            temp=n%(int)Math.pow(10,i);
            curr=temp/(int)Math.pow(10,i-1);
            low=temp%(int)Math.pow(10,i-1);
            if(curr==1)
                total+=high*(int)Math.pow(10,i-1)+low+1;
            else if(curr<1)
                total+=high*(int)Math.pow(10,i-1);
            else
                total+=(high+1)*(int)Math.pow(10,i-1);
            ++i;
        }
        return total;
    }
}
posted @ 2020-01-01 22:27  31楼下小黑  阅读(167)  评论(0编辑  收藏  举报