您的位置:首页 > 理论基础 > 数据结构算法

数据结构与算法面试题80道(30)

2016-03-14 12:19 351 查看
30.在从1到n的正数中1出现的次数

题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。

例如输入12,从1到12这些整数中包含1 的数字有1,10,11和12,1一共出现了5次。

分析:这是一道广为流传的google面试题。

最优美的算法就是按位进行分析

我们以21034来分析

如果将个位设为1,只考虑个位数上面的1,会有多少个1。(从1031->1021->1011->...->0001) 104个数包含104个1

如果将十位设为1,只考虑十位数上面的1,会有多少个1。(从101x->091x->...->001x)10*10个1,(x为0到9,不考虑个位上的1)

如果将百位设为1,只考虑百位数上面的1,会有多少个1。如果和刚才一样将百位设为1,发现千位只能为0,否则构成的数就比本身大了。

  那么如果百位为0,将百位设为1,会有多少个1。(01xx),包含x个1,这时候的x为100。

如果将千位设为1,只考虑千位数上面的1,会有多少个1。这时候也比较特殊,因为千位本来就为1。那么不仅要考虑万位有多少个数,还要考虑百位、十位、个位上有多少数。

  万位上只能是1,不能是2,如果为2,可能构成比本事大的数。那么千位为1,只考虑千位的1,会有多少1。

  1000+34个(万位为1,三位数有一千种组合;万位为2,后面三位数不能大于原来的数,所以是34)

如果将万位设为1,只考虑万位数上面的1,会有多少个1。0个,因为不存在十万位。

综上所述:将N分为高位,当前位,低位,1的个数为count。

如果当前位为0,count应该加上高位的值*低位的位数。

如果当前位为1,count应该加上高位的值*低位的位数,再加上低位的个数(低位的数值+1)

如果当前位大于1,count应该加上高位的个数*低位的位数

如果不明白,根据代码分析

#include<iostream>
#include<cstring>
#include<stdio.h>
#include<stack>
using namespace std;
int howMachOne(int n){
int count=0;//记录总共有多少个1
int factor=1;//记录低位的位数
int low;//记录低位的数值
int current;//记录当前位数的值
int hight;//记录高位的值
while(n/factor!=0){
low=n%factor;
current=(n/factor)%10;
hight=n/(factor*10);
switch(current){
case 0:
count+=hight*factor;//高位的值*低位的位数
break;
case 1:
count+=hight*factor+low+1;//高位的值*低位的个数+低位的个数
break;
default:
count+=(hight+1)*factor;//高位的个数*低位的位数
break;
}
factor*=10;
}
return count;
}

int main(){
int count=howMachOne(12);
cout<<count<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: