在从1到n的正数中1出现的次数
来源:互联网 发布:vb.net 正则表达式 编辑:程序博客网 时间:2024/06/15 00:49
题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。
例如输入12,从1到12这些整数中包含1的数字有1,10,11和12,1一共出现了5次。
最简单思路,就是从1-n一个刚数字进行判断然后计数即可,
int NumberOf1BeforeBetween1AndN_Solution1(unsigned int n){int number = 0;// Find the number of 1 in each integer between 1 and nfor(unsigned int i = 1; i <= n; ++ i)number += NumberOf1(i);return number;}int NumberOf1(unsigned int n){int number = 0;while(n){if(n % 10 == 1)number ++;n = n / 10;}return number;}
这个思路有一个非常明显的缺点就是每个数字都要计算1在该数字中出现的次数,因此时间复杂度是O(n)。当输入的n非常大的时候,需要大量的计算,运算效率很低。这里引入新的思路,以n=21345为例,可以分成两部分1-1345和1346-21345,先分析1236-21345这一部分20000个数字,1-1345迭代即可。
对于1236-21345分析1出现的次数,可以分两种情况:
a 1在最高位(万),一共在10000-19999中出现过,一共10^4次,当然这是在这个最高位数字2大于1的情况下,如 最高位原数字就是等于1,如11345则此时统计最高位1出现次数很明显就只有1345+1次
b 1在其他为(后四位),选取一位为1,有len-1=4种选法,每种指定1后,剩下3位有10^3种情况,再考虑最高位后1出现此时最高位数字2×4×10^3。
剩下的对1-1345类似分析即可。
代码:
int powerbase10(int n){int res=1;for(int i=0;i<n;i++) res*=10;return res;}//10^nint numberof1(string str){if(str.size()<1)return 0;int first=str[0]-'0';unsigned int len=static_cast<unsigned int>(str.size());if(len==1&&first==0)return 0;if(len==1&&first>0){return 1; }int num_first=0;int num_other=first*(len-1)*powerbase10(len-2);int numrecursive=numberof1(str.substr(1));if(first>1)num_first=powerbase10(len-1);else if(first==1)num_first=atoi(str.substr(1).c_str())+1;return num_first+num_other+numrecursive;}
阅读全文
0 0
- 从1到N正数中1出现的次数
- 从1到n正数中1出现的次数
- 在从1到n的正数中1出现的次数
- 在从1到n的正数中1出现的次数
- 讨论google面试题 - 在从1到n的正数中1出现的次数
- 在从1到n的正数中1出现的次数
- 在从1到n的正数中1出现的次数
- 30、在从1到n的正数中1出现的次数
- 求在从1到n的正数中1出现的次数
- 在从1到n的正数中1出现的次数
- 在从1到n的正数中1出现的次数
- 在从1到n的正数中1出现的次数
- 在从1 到n 的正数中1 出现的次数
- 在从1到n的正数中1出现的次数
- 在从1到n的正数中1出现的次数
- 30.在从1到n的正数中1出现的次数(数组)
- 在从1到n的正数中1出现的次数[算法]
- 30.在从1到n的正数中1出现的次数
- JAVA正则表达式:Pattern类与Matcher类详解(转)
- Android自定义Dialog顶部有条蓝色的线
- Cent OS 6_5(x86_64)下安装Oracle 11g
- 数据结构思维 第一章 接口
- HDFS分布式文件存储系统
- 在从1到n的正数中1出现的次数
- genromfs的使用及nuttx下romfs制作
- 奇妙的三维立体图
- hive udaf
- 使用队列实现栈
- hdu 1231
- 合并表记录
- 仿QQ左滑打开或删除
- NOIP模拟题 期望DP 礼物