这是一道广为流传的google面试题。用最直观的方法求解并不是很难,但遗憾的是效率不是很高;而要得出一个效率较高的算法,需要比较强的分析能力,并不是件很容易的事情。当然,google的面试题中简单的也没有几道。

硬上:O(nlogn)

 int NumberOf1(unsigned int n);

 int NumberOf1Between1AndN_Solution1(unsigned int n)
{
int number = ; for(unsigned int i = ; i <= n; ++ i)
number += NumberOf1(i); return number;
} int NumberOf1(unsigned int n)
{
int number = ;
while(n)
{
if(n % == )
number ++; n = n / ;
} return number;
}

方法二:

我们用一个稍微大一点的数字21345作为例子来分析。我们把从1到21345的所有数字分成两段,即1-1235和1346-21345。

先来看1346-21345中1出现的次数。1的出现分为两种情况:一种情况是1出现在最高位(万位)。从1到21345的数字中,1出现在10000-19999这10000个数字的万位中,一共出现了10000(104)次;另外一种情况是1出现在除了最高位之外的其他位中。例子中1346-21345,这20000个数字中后面四位中1出现的次数是2000次(2*103,其中2的第一位的数值,103是因为数字的后四位数字其中一位为1,其余的三位数字可以在0到9这10个数字任意选择,由排列组合可以得出总次数是2*103)。

至于从1到1345的所有数字中1出现的次数,我们就可以用递归地求得了。这也是我们为什么要把1-21345分为1-1235和1346-21345两段的原因。因为把21345的最高位去掉就得到1345,便于我们采用递归的思路。

分析到这里还有一种特殊情况需要注意:前面我们举例子是最高位是一个比1大的数字,此时最高位1出现的次数104(对五位数而言)。但如果最高位是1呢?比如输入12345,从10000到12345这些数字中,1在万位出现的次数就不是104次,而是2346次了,也就是除去最高位数字之后剩下的数字再加上1。

int NumberOf1(const char* strN);
int PowerBase10(unsigned int n); int NumberOf1Between1AndN_Solution2(int n)
{
if(n <= )
return ; char strN[];
sprintf(strN, "%d", n); return NumberOf1(strN);
} int NumberOf1(const char* strN)
{
if(!strN || *strN < '' || *strN > '' || *strN == '\0')
return ; int first = *strN - '';
unsigned int length = static_cast<unsigned int>(strlen(strN)); if(length == && first == )
return ; if(length == && first > )
return ; // 假设strN是"21345"
// numFirstDigit是数字10000-19999的第一个位中1的数目
int numFirstDigit = ;
if(first > )
numFirstDigit = PowerBase10(length - );
else if(first == )
numFirstDigit = atoi(strN + ) + ; // numOtherDigits是01346-21345除了第一位之外的数位中1的数目
int numOtherDigits = first * (length - ) * PowerBase10(length - );
// numRecursive是1-1345中1的数目
int numRecursive = NumberOf1(strN + ); return numFirstDigit + numOtherDigits + numRecursive;
} int PowerBase10(unsigned int n)
{
int result = ;
for(unsigned int i = ; i < n; ++ i)
result *= ; return result;
}

面试题32:从1到n整数中1出现的次数的更多相关文章

  1. 剑指Offer:面试题32——从1到n整数中1出现的次数(java实现)

    问题描述: 输入一个整数n,求1到n这n个整数的十进制表示中1出现的次数.例如输入12,从1到12这些整数中包含1的数字有1,10,11,12,1一共出现了5次. 思路:(不考虑时间效率的解法,肯定不 ...

  2. 【剑指Offer面试编程题】题目1373:整数中1出现的次数--九度OJ

    题目描述: 亲们!!我们的外国友人YZ这几天总是睡不好,初中奥数里有一个题目一直困扰着他,特此他向JOBDU发来求助信,希望亲们能帮帮他.问题是:求出1~13的整数中1出现的次数,并算出100~130 ...

  3. 剑指Offer的学习笔记(C#篇)-- 整数中1出现的次数(从1到n整数中1出现的次数)

    题目描述 求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1.10.11.12.13因此共出现6次,但是对于后面问题他就没辙了. ...

  4. 【剑指Offer】31、从1到n整数中1出现的次数

      题目描述:   求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1.10.11.12.13因此共出现6次,但是对于后面问题他 ...

  5. 【剑指Offer面试题】 九度OJ1517:链表中倒数第k个结点

    鲁棒性是指程序可以推断输入是否符合规范要求,并对不和要求的输入予以 合理的处理. 题目链接地址: http://ac.jobdu.com/problem.php?pid=1517 题目1517:链表中 ...

  6. 剑指offer——面试题32.1:分行从上到下打印二叉树

    void BFSLayer(BinaryTreeNode* pRoot) { if(pRoot==nullptr) return; queue<BinaryTreeNode*> pNode ...

  7. 剑指offer——面试题32:从上到下打印二叉树

    void BFS(BinaryTreeNode* pRoot) { if(pRoot==nullptr) { cout<<"empty binary tree!"< ...

  8. 【剑指offer 面试题38】数字在排序数组中出现的次数

    思路: 利用二分查找,分别查找待统计数字的头和尾的下标,最后做差加一即为结果. C++: #include <iostream> #include <vector> using ...

  9. 剑指offer——面试题15.2:判断两个整数m和n的二进制中相差多少位

    #include"iostream" using namespace std; int CountDifferentBit(int m,int n) { ,diff=m^n; wh ...

  10. 面试题32.从1到n整数中1出现的次数

    题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数.例如输入12,从 1到12这些整数中包含1的数字中1,10,11和12,1一共出现了5次 本题可以直接变量1到n的n个数然后分别计 ...

随机推荐

  1. Codeforces 578.C Weakness and Poorness

    C. Weakness and Poorness time limit per test 2 seconds memory limit per test 256 megabytes input sta ...

  2. springMVC参数的获取区别

    在springMVC中我们一般使用注解的形式来完成web项目,但是如果不明白springmvc的对于不同注解的应用场景就会很容易犯错误 1.什么是restful形式: 什么是RESTful restf ...

  3. python中如何优雅使用import

    http://note.youdao.com/noteshare?id=c55be6a8565f5eb586aa52244b3af010

  4. 「PLC」PLC基本编程

    PLC中无非就是三大量:开关量(数字量).模拟量.脉冲量.只在搞清楚三者之间的关系,你就能熟练的掌握PLC了. PLC编程算法(一) 1. 开关量也称逻辑量,指仅有两个取值,0或1.ON或OFF.它是 ...

  5. 一小时了解数据挖掘⑤数据挖掘步骤&常用的聚类、决策树和CRISP-DM概念

    一小时了解数据挖掘⑤数据挖掘步骤&常用的聚类.决策树和CRISP-DM概念 接前面系列4篇: 一小时了解数据挖掘①:解析常见的大数据应用案例 一小时了解数据挖掘②:分类算法的应用和成熟案例解析 ...

  6. MappedByteBuffer以及ByteBufer的底层原理

    最近在用java中的ByteBuffer,一直不明所以,尤其是对MappedByteBuffer使用的内存映射这个概念云里雾里. 于是首先补了物理内存.虚拟内存.页面文件.交换区的只是:小科普——物理 ...

  7. jquery 事件对象属性小结

    使用事件自然少不了事件对象. 因为不同浏览器之间事件对象的获取, 以及事件对象的属性都有差异, 导致我们很难跨浏览器使用事件对象. jQuery中统一了事件对象, 当绑定事件处理函数时, 会将jQue ...

  8. DOM基础操作

    本文地址:http://www.cnblogs.com/veinyin/p/7606972.html  1 访问 HTML 元素 常用方法 document.getElementById(" ...

  9. CF148A Insomnia cure

    公主睡前数龙, 每隔k, l, m, n只都会用不同的技能攻击龙. 假定共数了d只龙, 问共有多少龙被攻击了. 思路: 用一个visit数组记录被攻击过的dragon, 最后遍历visit数组统计被攻 ...

  10. CRF原理解读

    概率有向图又称为贝叶斯网络,概率无向图又称为马尔科夫网络.具体地,他们的核心差异表现在如何求  ,即怎么表示  这个的联合概率. 概率图模型的优点: 提供了一个简单的方式将概率模型的结构可视化. 通过 ...