Write a method to count the number of 2s between 0 and n
2014-01-21 22:46
555 查看
转自出处
Cracking the coding interview--Q20.4
March 1, 2013作者:Hawstein
出处:http://hawstein.com/posts/20.4.html
声明:本文采用以下协议进行授权: 自由转载-非商用-非衍生-保持署名|Creative Commons BY-NC-ND 3.0 ,转载请注明作者及出处。
题目
原文:Write a method to count the number of 2s between 0 and n.
译文:
写一个函数,计算0到n之间2的个数。
解答
最简单直观的方法就是对于0到n之间的数,一个个地去统计2在它们上出现的个数, 然后累加起来即可。求2在某个数上出现的次数需要O(logn)的时间,一共有n个数, 所以共需要O(nlogn)的时间。代码如下:
int Count2(int n){ int count = 0; while(n > 0){ if(n%10 == 2) ++count; n /= 10; } return count; } int Count2s1(int n){ int count = 0; for(int i=0; i<=n; ++i) count += Count2(i); return count; }
上述方法最大的问题就是效率,当n非常大时,就需要很长的运行时间。 想要提高效率,就要避开暴力法,从数字中找出规律。对于这道题, 《编程之美》已经给出了很漂亮的解法,这里再简述一下。
假设一个5位数N=abcde,我们现在来考虑百位上出现2的次数,即,从0到abcde的数中, 有多少个数的百位上是2。分析完它,就可以用同样的方法去计算个位,十位,千位, 万位等各个位上出现2的次数。
当百位c为0时,比如说12013,0到12013中哪些数的百位会出现2?我们从小的数起, 200~299, 1200~1299, 2200~2299, … , 11200~11299, 也就是固定低3位为200~299,然后高位依次从0到11,共12个。再往下12200~12299 已经大于12013,因此不再往下。所以,当百位为0时,百位出现2的次数只由更高位决定, 等于更高位数字(12)x当前位数(100)=1200个。
当百位c为1时,比如说12113。分析同上,并且和上面的情况一模一样。 最大也只能到11200~11299,所以百位出现2的次数也是1200个。
上面两步综合起来,可以得到以下结论:
当某一位的数字小于2时,那么该位出现2的次数为:更高位数字x当前位数
当百位c为2时,比如说12213。那么,我们还是有200~299, 1200~1299, 2200~2299, … , 11200~11299这1200个数,他们的百位为2。但同时,还有一部分12200~12213, 共14个(低位数字+1)。所以,当百位数字为2时, 百位出现2的次数既受高位影响也受低位影响,结论如下:
当某一位的数字等于2时,那么该位出现2的次数为:更高位数字x当前位数+低位数字+1
当百位c大于2时,比如说12313,那么固定低3位为200~299,高位依次可以从0到12, 这一次就把12200~12299也包含了,同时也没低位什么事情。因此出现2的次数是: (更高位数字+1)x当前位数。结论如下:
当某一位的数字大于2时,那么该位出现2的次数为:(更高位数字+1)x当前位数
根据上面得出的3条结论,我们可以编写出代码如下:
int Count2s(int n){ int count = 0; int factor = 1; int low = 0, cur = 0, high = 0; while(n/factor != 0){ low = n - (n/factor) * factor;//低位数字 cur = (n/factor) % 10;//当前位数字 high = n / (factor*10);//高位数字 switch(cur){ case 0: case 1: count += high * factor; break; case 2: count += high * factor + low + 1; break; default: count += (high + 1) * factor; break; } factor *= 10; } return count; }
如果我们把问题一般化一下:写一个函数,计算0到n之间i出现的次数,i是1到9的数。 这里为了简化,i没有包含0,因为按以上的算法计算0出现的次数, 比如计算0到11间出现的0的次数,会把1,2,3,4…视为01,02,03,04… 从而得出错误的结果。所以0是需要单独考虑的,为了保持一致性,这里不做讨论。 将上面的三条结论应用到这就是:
当某一位的数字小于i时,那么该位出现i的次数为:更高位数字x当前位数 当某一位的数字等于i时,那么该位出现i的次数为:更高位数字x当前位数+低位数字+1 当某一位的数字大于i时,那么该位出现i的次数为:(更高位数字+1)x当前位数
代码如下:
int Countis(int n, int i){ if(i<1 || i>9) return -1;//i只能是1到9 int count = 0; int factor = 1; int low = 0, cur = 0, high = 0; while(n/factor != 0){ low = n - (n/factor) * factor;//低位数字 cur = (n/factor) % 10;//当前位数字 high = n / (factor*10);//高位数字 if(cur < i) count += high * factor; else if(cur == i) count += high * factor + low + 1; else count += (high + 1) * factor; factor *= 10; } return count; }
全书题解目录:
Cracking the coding interview–问题与解答
全书的C++代码托管在Github上:
https://github.com/Hawstein/cracking-the-coding-interview
相关文章推荐
- Give a very good method to count the number of ones in a "n" (e.g. 32) bit number.
- Write a method that counts the number of occurrences of a given character in a string
- python int to binary and count the number of 1
- (斐波那契总结)Write a method to generate the nth Fibonacci number (CC150 8.1)
- How to count the number of threads in a process on Linux
- 1.3 Given two strings, write a method to decide if one is a permutation of the other.
- Write a method to print the last K lines of an input file using C++
- function to count the number of "1" of one byte
- How to count the occurrences of a number?
- Write an Efficient Method to Check if a Number is Multiple of 3(快速判断3的倍数)
- Write an Efficient Method to Check if a Number is Multiple of 3
- Write a Servlet Application that uses a cookie to track the number of times a user visits a web site
- Macro to count number of arguments
- The number of method references in a .dex file cannot exceed 64k API 17
- Error Number : 1547 Error Message: Column count of mysql.proc is wrong. Expected 20, found 16. The
- How to calculate the number of parameters in CNNs?
- error:Cannot assign to 'self' outside of a method in the init family
- 三角形的数目 Count the number of possible triangles
- The maximum number of cell styles was exceeded. You can define up to 4000 styles
- Given constant integers x and t, write a function that takes no argument and returns true if the function has been called x number of times in last t secs.