剑指offer第三十一题目 整数1出现的个数

题目:

解法:

第一种:直接从1到n呗,

              每个数字,我们从个位,十位,到最高位分析,有多少个就加上;

              然后从1遍历到n,最后所有的加上,就是总数呗。

              我们分析一下时间复杂度。每个数字的分析,肯定是lg(N)(肯定是以10为底,n的对数)

              从1到n,那么时间复杂度就是nlogn

               我没写,参考   https://blog.csdn.net/weixin_37672169/article/details/80950378

第二种,trick

              作为一道分析数字规律的题目,我败了,但是查了好多博客,我感觉我参考的这种方法是最好的,为什么?

              参考地址 :https://blog.csdn.net/littlehaes/article/details/92805867

/*
1,2,...n这n个数中
x位上每隔(x*10)个数出现x个1, n中有n/(x*10)个完整的(x*10),以百位为例,就是n中有n/1000个完整的1000, 分别是1~~1000,1001~~2000, 2001~~3000,...(n/1000 - 1)*1000 + 1~~(n/1000)*1000
最后还可能剩下不足1000的部分, 也就是从(n/1000)*1000+1~~n, 百位的情况对应n%1000

不足(x*10)的部分,也就是n%(x*10)的部分, x位上也有可能出现1
如果n%(x*10)<x, x位上没有1
如果n%(x*10)>2*x-1, x位上有x个1
如果n%(x*10)>=x && n%(x*10)<=2*x-1, x位上有n%(x*10) - x + 1个1
*/
public class Solution {
    public int NumberOf1Between1AndN_Solution(int n) {
        int count = 0;
        for(int i=1; i<=n; i*=10){
            count += n/(i*10) * i;
            if(n%(i*10) > 2*i-1)
                count += i;
            else if(n%(i*10)>=i)
                count += n%(i*10) - i + 1;
        }
        return count;
    }
}

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章