`
pandonix
  • 浏览: 400987 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

计算1到N中包含数字1的个数

阅读更多

今天看到一道有趣的算法题,题目如下:

N为正整数,计算从1到N的所有整数中包含数字1的个数。比如,N=10,从1,2...10,包含有2个数字1。

 

相信很多人都能立刻得出以下的解法:

  for(n:N)

  {

          判断n包含1的个数;

          累加计数器;

  }

这是最直接的解法,但遗憾的是,时间复杂程度为O(N*logN)。因为还需要循环判断当前的n的各位数,该判断的时间复杂程度为O(logN)。

接下来就应该思考效率更高的解法了。说实话,这道题让我想起另外一道简单的算法题:

N为正整数,计算从1到N的整数和。

很多人都采用了循环求解。然后利用初等数学知识就知道S=N*(N+1)/2,所以用O(1)的时间就可以处理。

再回到本道题目,同理应该去寻找到结果R与N之间的映射关系。

分析如下:

假设N表示为a[n]a[n-1]...a[1],其中a[i](1<=i<=n)表示N的各位数上的数字。

c[i]表示从整数1到整数a[i]...a[1]中包含数字1的个数。

x[i]表示从整数1到10^i - 1中包含数字1的个数,例如,x[1]表示从1到9的个数,结果为1;x[2]表示从1到99的个数,结果为20;

当a[1]=0时,c[1] = 0;

当a[1]=1时,c[1] = 1;

当a[1]>1时,c[1] = 1;

 

当a[2]=1时,c[2] = a[1] +1+ c[1] + x[1];

当a[2]>1时,c[2] = a[2]*x[1]+c[1]+10;

 

当a[3]=1时,c[3] = a[2]*a[1] +1+ c[2] + x[2];

当a[3]>1时,c[3] = a[3]*x[2]+c[2]+10^2;

......

 

以此类推

当a[i]=1时,c[i] = a[i-1]*...*a[1] +1+ c[i-1]+x[i-1];

当a[i]>1时,c[i] = a[i]x[i-1]+c[i-1]+10^(i-1);

 

 

实现的代码如下:

    public static int search(int _n)   
    {   
        int N = _n/10;   
        int a1 = _n%10,a2;   
        int x = 1;
        int ten = 10;
        int c = a1 == 0?0:1;
        while(N > 0)   
        {   
            a2 = N%10;
            if(a2 == 0);
            else if(a2 == 1)c = a1 + 1 + x + c;   
            else c = a2*x + c + ten;   
            a1 = 10*a1 + a2;     
            N /=10;   
            x = 10*x + ten;
            ten *= 10; 
        }   
        return c;   
    }

 

 

而以上解法的时间复杂程度只有O(logN)

 

如果您路过这里,您有更好的解法吗?:)

3
0
分享到:
评论
6 楼 waiting90 2009-01-11  
lggege 写道

StringBuffer.append() 将它们拼成一个String, 再从头到尾数

这样很慢,很慢...
5 楼 pandonix 2008-06-19  
非常感谢ywergs,以前的算法确实存在问题。惭愧啊,分析不仔细。
问题原因:
代码中没有考虑到a1=0的情况,因为如果a1=0,则c1=0。造成当a2=1,a1=0时,按照c2=a1+1+x1+c1来计算,而c1被初始化为1,所以c2=0+1+1+1=3。
问题解决:
初始化c1时,需要根据a1来初始化,其中c1=a1==0?0:1
这样一来就可以测试:
N(20) = 2*1+10 = 12;N(19) = 9 + 1 + 1 + 1 = 12;所以N(20) = N(19)
N(10) = 0 + 1 + 1 = 2;

再次感谢ywergs,欢迎继续讨论和拍砖
4 楼 ywergs 2008-06-19  
恕我愚笨,我怎么觉得LZ的这个有点问题呢?
比如,当我们用20来测试时,他应该走入else语句!
那么 c20 = 2 * 1 + 1 + 10 = 13
但从直观角度来看数字20 和 19 他们区间包含一个数应该是一样的,可是,如果算19的话,应该走的是if的,这时候, c19 = 9 + 1 + 1 + 1 = 12
从而有:
    c20 != c19
当然,我也为LZ的精湛思路所折服!
不过我也没有想到一个比较好的方法!
写到这里,发觉根本不用20来做测试,就是用10来做测试就有问题了!
按照LZ的思路,10的时候,算出来 应该是 3 ,可是,1-10之间只有2个1的!
3 楼 jasongreen 2008-06-18  
google面试题阿
2 楼 pandonix 2008-06-18  
楼上的解法不错,但时间复杂程度也是O(N+logN)以上,同时也忽略了API,Integer.parseInt的处理时间。
1 楼 lggege 2008-06-18  
StringBuffer.append()

将它们拼成一个String, 再从头到尾数

相关推荐

    C++计算一个数字的二进制中0或1的个数原理及代码

    ### C++ 计算一个数字的二进制中0或1的个数原理及代码解析 在计算机科学中,二进制表示法是基础之一,它不仅被用于数据存储,还在算法设计、加密技术以及系统优化等多个方面发挥着重要作用。本篇文章将详细探讨如何...

    (android demo)算法实现:计算十进制数N的二进制形式中包含数字1的个数

    在Android开发中,我们经常会遇到...总结来说,计算十进制数N的二进制形式中包含数字1的个数,既可以通过简单的位检查,也可以通过位操作优化。理解这些算法对于提升Android开发中的问题解决能力和代码效率至关重要。

    给定一个十进制正整数N,程序输出从1到N的所有整数中,“1”出现的个数。DMU

    在本题目中,我们需要编写一个C语言程序,用于计算从1到给定正整数N之间所有整数中数字"1"出现的总次数。这是一个典型的字符串处理和数学计算问题,涉及到了数字转换、字符串遍历以及计数算法。下面我们将深入探讨这...

    计算1的个数

    因此,计算1的个数实际上是在问:在0到N(包含N)的整数中,它们的二进制表示一共包含多少个1。 要解决这个问题,我们可以采用几种不同的算法策略。一种常见方法是逐个检查每个数字,并统计其二进制表示中的1。这个...

    1-n中缺失2个数字,O(n)时间内找出它们

    因为1到n中每对不同的数字异或后为奇数,所以`result`的二进制表示中1的个数应为偶数,但因为我们有两个缺失的数字,导致实际上的1的个数为奇数。我们可以利用这一特点找到一个规律。 4. 找到`result`的最右边的一个...

    统计字符串中数字的个数

    ### 统计字符串中数字的个数 #### 实验内容 本实验的主要目的是设计并实现一个程序,用于统计一个特定字符串中所有数字的出现次数,并按照数字从小到大的顺序输出这些数字及其出现次数。 #### 输入格式 - **Input...

    C++求1到n中1出现的次数以及数的二进制表示中1的个数

    例如输入 12,从 1 到 12 这些整数中包含 1 的数字有 1, 10, 1 1 和 12, 1 一共出现了 5 次 代码实现(GCC编译通过): #include stdio.h #include stdlib.h int count1(int n); int count2(int n); int main...

    统计1到n之间所有含1的数字个数,并找出n以内最大的那个f(m)=m的值

    统计1到n之间所有含1的数字个数f(n),并找出n以内最大的那个f(m)=m的值,f(n)的时间复杂度为O(logn),找最大的那个f(m)=m的值的时间复杂度为O(n)。... 判断n包含1的个数; 累加计数器; } 完全一致

    计算顺序数列某一数字出现的个数

    在编程领域,计算顺序数列中某一数字出现的个数是一项常见的任务,它涉及到数组处理、计数算法以及条件判断等基础知识。顺序数列通常指的是一个由0开始,按照自然数顺序排列的序列,例如0, 1, 2, 3, ..., n。这个...

    LabView 计算整数N内所有的素数

    在这个特定的示例中,“LabView 计算整数N内所有的素数”指的是利用LabView来编写一个程序,该程序能够找出从1到一个指定整数N之间所有素数。 素数是大于1且除了1和它自身以外没有其他正因数的自然数。判断一个数...

    输入一个自然数n,求 ,同时统计结果中有多少个0。

    标题中的“输入一个自然数n,求 ,同时统计结果中有多少个0。”是一个关于计算阶乘(Factorial)的问题,并且需要我们同时计算阶乘结果中0的数量。在这个问题中,"n!"代表n的阶乘,即1×2×3×...×n。 阶乘是数学...

    从0到N的数中总共包含1的数目

    标题 "从0到N的数中总共包含1的数目" 指的是计算从0到一个整数N之间所有数中数字1出现的总次数。这个主题涉及到位运算、数学和编程,特别是对于十进制和二进制的转换及计数。在计算机科学中,这类问题通常出现在算法...

    计算键盘上所有输入字符的个数

    总的来说,计算键盘输入字符的个数看似简单,但实际涉及到字符编码、字符串处理、性能优化等多个方面的知识。通过学习和实践这样的程序,我们可以提升对文本处理的理解,同时锻炼我们的编程技巧。

    n的阶乘问题--阶乘位数--阶乘末尾0的个数

    本文将深入探讨“n的阶乘问题”,包括阶乘的定义、计算阶乘位数的方法以及如何确定阶乘末尾零的个数。 首先,阶乘是指一个正整数n与小于等于它的所有正整数的乘积。用数学符号表示为`n! = n × (n-1) × (n-2) × ....

    位1的个数1

    在计算机科学中,汉明重量(Hamming Weight)是指一个数字在二进制表示下“1”的个数。这个问题是编程挑战网站LeetCode上的一个问题,要求编写一个函数来计算无符号整数的汉明重量。这里我们将深入探讨如何解决这个...

    枚举的实现求得1-1000所有出现1的数字并计算出现1的个数

    在这个问题中,我们面临的是一个计数问题,需要找出1到1000之间所有包含数字1的整数,并计算其中数字1出现的总次数。下面将详细讨论这个问题的解决方案以及枚举在其中的作用。 首先,我们要明确问题的要求:找出1到...

    C语言编程训练:循环结构-求阶乘末尾零个数

    输入的第一行是一个单个的确定的正整数T,他指名接下来的数字的个数,然后是 T 行,每一行包括一个确定的正整数N,1&lt;=N&lt;=1,000,000,000。 【输出说明】 对每一个数字N,产生一行输出包括一个非负整数Z(N)。 【样例...

    剑指Offer(Python多种思路实现):1~n整数中1出现的次数

    例如,输入12,1~12这些整数中包含1的数字有1,10,11,12一共出现了5次。 解题思路一:直接累加1~n中每个整数中1出现的次数。 class Solution: def NumberOf1Between1AndN_Solution(self, n): # write code here...

    1-999中能被3整除,且至少有一位数字是5的所有整数

    1-999中能被3整除,且至少有一位数字是5的所有整数,经典例题

Global site tag (gtag.js) - Google Analytics