【有趣的面试算法题】之二 求1~n的整数中1的个数,递归统计区间块中1的数量
来源:互联网 发布:mac os sierra安装教程 编辑:程序博客网 时间:2024/05/29 05:54
题目:求1~n的整数中1的个数。
常规做法是,先写一个右移判1的子函数,计算每个数里面的1的个数,然后遍历1~n,取和,就是答案。
在百度文库(http://wenku.baidu.com/view/6722a969af1ffc4ffe47ac18.html)中看到有这样一个解法:
//计算整数 1~n 中的1的个数总和ULONGLONG Sum1s(ULONGLONG n) { ULONGLONG iCount = 0; ULONGLONG iFactor = 1; ULONGLONG iLowerNum = 0; ULONGLONG iCurrNum = 0; ULONGLONG iHigherNum = 0; while(n / iFactor != 0) { iLowerNum = n - (n / iFactor) * iFactor; iCurrNum = (n / iFactor) % 10; iHigherNum = n / (iFactor * 10); switch(iCurrNum) { case 0: iCount += iHigherNum * iFactor; break; case 1: iCount += iHigherNum * iFactor + iLowerNum + 1; break; default: iCount += (iHigherNum + 1) * iFactor; break; } iFactor *= 10; } return iCount;}
据它说“ 这个方法只要分析N就可以得到f(N),避开了从1到N的遍历,输入长度为Len的数字N的时间复杂度为O(Len),即为O(ln(n)/ln(10)+1)。在笔者的计算机上,计算N=100 000 000,相对于第一种方法的40秒时间,这种算法不到1毫秒就可以返回结果,速度至少提高了40 000倍。”
但不知为何没能运行正确,尽管没有看懂思路,但觉得还蛮有启发,直接从 n 入手分析,避免遍历1~n,于是我研究一会之后,观察到有这么一个现象:在二进制表示中,N位的000...000 ~111...111 之间0 与 1的个数相等!如下图所示:
于是基于递归法的实现方法如下所示,并且递归深度不会超过 n 的最高非0 bit位数,比较快吧?
//计算整数 1~n 中的1的个数总和ULONGLONG Sum1s(ULONGLONG n) { if (n <= 2) { return n; } ULONGLONG iFactor = 3; ULONGLONG iLen = 1; while(n >= iFactor) //找出最大的、小于n的、bit位全部为1 的数 { iFactor <<=1; iFactor |= 1; ++iLen; } iFactor >>=1; ULONGLONG iCount =((iFactor + 1)*iLen)>>1; //这一片区域的1 0 数量相等 if ( iFactor == n) { return iCount; } else { return (iCount + n - iFactor + Sum1s(n & (iFactor))); } }
- 【有趣的面试算法题】之二 求1~n的整数中1的个数,递归统计区间块中1的数量
- 统计整数n的二进制表示中1的个数
- 求整数N的二进制形式中1的个数
- 求整数n的二进制表达式中1的个数
- 求整数N的二进制表示中1的个数
- 牛客网 求1到n 整数中1的个数
- 求整数1……n中0的个数
- 求一个整数N,二进制中1的个数
- (阶乘末尾0的个数的求法)求1~N中因子的数量的方法
- 算法题:求N!末尾0的个数和求二进制数中1的个数
- 【编程之美】读书笔记:求1到N之间整数中出现1的个数
- 求任意整数中1的个数
- 求整数中1的个数
- 算法--求0到N中所有1的个数
- 统计一个整数n的二进制表示中1的个数的几种解法
- 十进制整数区间[1, N]中数字1出现的个数
- 统计从1到N的所有整数中出现1的个数
- 统计整数n的二进制展开数中1的个数
- 探秘widget之launcher添加widget的流程分析
- Thread,RunLoop初识
- 用Mouse_event()来模拟鼠标操作
- itunes更新固件常用路径
- 一不小心踏进Android开发: TPMini大眼睛使用PS3蓝牙手柄(三)开发环境
- 【有趣的面试算法题】之二 求1~n的整数中1的个数,递归统计区间块中1的数量
- openGL——视图
- 如何去除laucher里面的图标
- 字符串搜索方法rangeOfString
- Android学习之 ActionBar 和 SherlockActionBar
- 配置tomcat访问日志
- Android异步处理四:AsyncTask的实现原理 .
- 集合使用
- Android下使用c++11的测试