计算从1到N中1的出现次数
来源:互联网 发布:淘宝客服兼职多少钱 编辑:程序博客网 时间:2024/05/01 05:53
给定一个十进制整数N,求出从1到N的所有整数中出现"1"的个数。
例如:N=2,1,2出现了1个"1"。
N=12,1,2,3,4,5,6,7,8,9,10,11,12。出现了5个"1"。
最直接的方法就是从1开始遍历到N,将其中每一个数中含有"1"的个数加起来,就得到了问题的解。
01
public
long
CountOne3(
long
n)
02
{
03
long
i =
0
,j =
1
;
04
long
count =
0
;
05
for
(i =
0
; i <= n; i++)
06
{
07
j = i;
08
while
(j !=
0
)
09
{
10
if
(j %
10
==
1
)
11
count++;
12
j = j /
10
;
13
}
14
}
15
return
count;
16
}
此方法简单,容易理解,但它的问题是效率,时间复杂度为O(N * lgN),N比较大的时候,需要耗费很长的时间。
我们换个角度思考,给定一个N,我们分析1~N中的数在每一位上出现1的次数的和,看看每一位上"1"出现的个数的和由什么决定。
1位数的情况:在解法二中已经分析过,大于等于1的时候,有1个,小于1就没有。
2位数的情况:N=13,个位数出现的1的次数为2,分别为1和11,十位数出现1的次数为4,分别为10,11,12,13,所以f(N) = 2+4。N=23,个位数出现的1的次数为3,分别为1,11,21,十位数出现1的次数为10,分别为10~19,f(N)=3+10。
由此我们发现,个位数出现1的次数不仅和个位数有关,和十位数也有关,如果个位数大于等于1,则个位数出现1的次数为十位数的数字加1;如果个位数为0,个位数出现1的次数等于十位数数字。而十位数上出现1的次数也不仅和十位数相关,也和个位数相关:如果十位数字等于1,则十位数上出现1的次数为个位数的数字加1,假如十位数大于1,则十位数上出现1的次数为10。
3位数的情况:
N=123,个位出现1的个数为13:1,11,21,…,91,101,111,121。十位出现1的个数为20:10~19,110~119。百位出现1的个数为24:100~123。
我们可以继续分析4位数,5位数,推导出下面一般情况: 假设N,我们要计算百位上出现1的次数,将由三部分决定:百位上的数字,百位以上的数字,百位一下的数字。
如果百位上的数字为0,则百位上出现1的次数仅由更高位决定,比如12013,百位出现1的情况为100~199,1100~1199,2100~2199,…,11100~11199,共1200个。等于更高位数字乘以当前位数,即12 * 100。
如果百位上的数字大于1,则百位上出现1的次数仅由更高位决定,比如12213,百位出现1的情况为100~199,1100~1199,2100~2199,…,11100~11199,12100~12199共1300个。等于更高位数字加1乘以当前位数,即(12 + 1)*100。
如果百位上的数字为1,则百位上出现1的次数不仅受更高位影响,还受低位影响。例如12113,受高位影响出现1的情况:100~199,1100~1199,2100~2199,…,11100~11199,共1200个,但它还受低位影响,出现1的情况是12100~12113,共114个,等于低位数字113+1。
综合以上分析,写出如下代码:
01
public
long
CountOne2(
long
n)
02
{
03
long
count =
0
;
04
long
i =
1
;
05
long
current =
0
,after =
0
,before =
0
;
06
while
((n / i) !=
0
)
07
{
08
current = (n / i) %
10
;
09
before = n / (i *
10
);
10
after = n - (n / i) * i;
11
12
if
(current >
1
)
13
count = count + (before +
1
) * i;
14
else
if
(current ==
0
)
15
count = count + before * i;
16
else
if
(current ==
1
)
17
count = count + before * i + after +
1
;
18
19
i = i *
10
;
20
}
21
return
count;
22
}
此算法的时间复杂度仅为O(lgN),且没有递归保存现场的消耗和堆栈溢出的问题。
- 判断点是否在三角形内部
- 利用数组索引进行排序
- 递归算法
- 求解最大公约数问题
- 一次腾讯招聘的笔试和面试题
- 各种进制转换的原理分析介绍
- 极大极小博弈树Minimax Game Tree介绍
- 合并排序算法介绍
- 双向队列算法的PHP实现
- 将一个数组的元素顺序打乱
- 高频笔试题strcpy()的写法
- 寻找和为给定数的连续正整数数列
- HTML (44)
- CSS (105)
- JavaScript (232)
- JQuery (53)
- Ajax (34)
- PHP (314)
- Java (39)
- C/C++ (35)
- ActionScript (21)
- PhotoShop (4)
- XML (1)
- WordPress (9)
- 数据结构 (14)
- 计算机算法 (56)
- 数据库技术 (66)
- 操作系统 (1)
- 互联网时代 (160)
- 软件项目 (27)
- 编程思想 (57)
- 搜索引擎优化 (31)
- Web设计理念 (77)
- 软件架构技术 (31)
- 信息化工具 (12)
- 广告设计 (7)
- 程序人生 (18)
- 喃喃细语 (61)
- 计算从1到N中,1出现的次数
- 计算从1到N中1的出现次数
- 计算从1到N中1的出现次数
- 计算从1到n的正整数中1出现的次数!
- 计算从1到n整数中K出现的次数
- 从1到N正数中1出现的次数
- 从1到n整数中1出现的次数
- 从1到n整数中1出现的次数
- 从1到n整数中1出现的次数
- 从1到n整数中1出现的次数
- 从1到n整数中1出现的次数
- 从1到n整数中1出现的次数
- 从1到n整数中1出现的次数
- 从1到n整数中1出现的次数
- 从1到n整数中1出现的次数
- 从1到n整数中1出现的次数
- 从1到n整数中1出现的次数
- 从1到n整数中1出现的次数
- Android开发规范之编码规范
- (转载)Hibernate映射解析——七种映射关系
- 我先走的那一步
- 单向一对一唯一外键关联实例
- Android开发环境搭建
- 计算从1到N中1的出现次数
- leetcode第一刷_Sort List
- FreeSwitch安装音乐文件遇到的问题
- 单向一对一主键关联实例
- C++中基本类型
- c语言实现的静态链表 哥们第一篇 请各位大牛多指教
- TestFlight——完美的iOS App测试方案
- PMP-产品范围与项目范围区别
- C#中子线程操作主线程中窗体上控件的方法