今天看到一道有趣的算法题,题目如下:
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)
如果您路过这里,您有更好的解法吗?:)
分享到:
相关推荐
### C++ 计算一个数字的二进制中0或1的个数原理及代码解析 在计算机科学中,二进制表示法是基础之一,它不仅被用于数据存储,还在算法设计、加密技术以及系统优化等多个方面发挥着重要作用。本篇文章将详细探讨如何...
在Android开发中,我们经常会遇到...总结来说,计算十进制数N的二进制形式中包含数字1的个数,既可以通过简单的位检查,也可以通过位操作优化。理解这些算法对于提升Android开发中的问题解决能力和代码效率至关重要。
在本题目中,我们需要编写一个C语言程序,用于计算从1到给定正整数N之间所有整数中数字"1"出现的总次数。这是一个典型的字符串处理和数学计算问题,涉及到了数字转换、字符串遍历以及计数算法。下面我们将深入探讨这...
因此,计算1的个数实际上是在问:在0到N(包含N)的整数中,它们的二进制表示一共包含多少个1。 要解决这个问题,我们可以采用几种不同的算法策略。一种常见方法是逐个检查每个数字,并统计其二进制表示中的1。这个...
因为1到n中每对不同的数字异或后为奇数,所以`result`的二进制表示中1的个数应为偶数,但因为我们有两个缺失的数字,导致实际上的1的个数为奇数。我们可以利用这一特点找到一个规律。 4. 找到`result`的最右边的一个...
### 统计字符串中数字的个数 #### 实验内容 本实验的主要目的是设计并实现一个程序,用于统计一个特定字符串中所有数字的出现次数,并按照数字从小到大的顺序输出这些数字及其出现次数。 #### 输入格式 - **Input...
例如输入 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的数字个数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来编写一个程序,该程序能够找出从1到一个指定整数N之间所有素数。 素数是大于1且除了1和它自身以外没有其他正因数的自然数。判断一个数...
标题中的“输入一个自然数n,求 ,同时统计结果中有多少个0。”是一个关于计算阶乘(Factorial)的问题,并且需要我们同时计算阶乘结果中0的数量。在这个问题中,"n!"代表n的阶乘,即1×2×3×...×n。 阶乘是数学...
标题 "从0到N的数中总共包含1的数目" 指的是计算从0到一个整数N之间所有数中数字1出现的总次数。这个主题涉及到位运算、数学和编程,特别是对于十进制和二进制的转换及计数。在计算机科学中,这类问题通常出现在算法...
总的来说,计算键盘输入字符的个数看似简单,但实际涉及到字符编码、字符串处理、性能优化等多个方面的知识。通过学习和实践这样的程序,我们可以提升对文本处理的理解,同时锻炼我们的编程技巧。
本文将深入探讨“n的阶乘问题”,包括阶乘的定义、计算阶乘位数的方法以及如何确定阶乘末尾零的个数。 首先,阶乘是指一个正整数n与小于等于它的所有正整数的乘积。用数学符号表示为`n! = n × (n-1) × (n-2) × ....
在计算机科学中,汉明重量(Hamming Weight)是指一个数字在二进制表示下“1”的个数。这个问题是编程挑战网站LeetCode上的一个问题,要求编写一个函数来计算无符号整数的汉明重量。这里我们将深入探讨如何解决这个...
在这个问题中,我们面临的是一个计数问题,需要找出1到1000之间所有包含数字1的整数,并计算其中数字1出现的总次数。下面将详细讨论这个问题的解决方案以及枚举在其中的作用。 首先,我们要明确问题的要求:找出1到...
输入的第一行是一个单个的确定的正整数T,他指名接下来的数字的个数,然后是 T 行,每一行包括一个确定的正整数N,1<=N<=1,000,000,000。 【输出说明】 对每一个数字N,产生一行输出包括一个非负整数Z(N)。 【样例...
例如,输入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的所有整数,经典例题