剑指 Offer JZ31 整数中1出现的次数(从1到n整数中1出现的次数)
Posted 程序字母K
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指 Offer JZ31 整数中1出现的次数(从1到n整数中1出现的次数)相关的知识,希望对你有一定的参考价值。
输入一个整数 n ,求1~n这n个整数的十进制表示中1出现的次数
例如,1~13中包含1的数字有1、10、11、12、13因此共出现6次
范围 | 1的个数 |
---|---|
0-9 | 1==1 |
0-99 | 1*10+10==20 |
0-999 | 20*10+100==300 |
0-9999 | 300*10+1000==4000 |
0-99999 | 4000*10+10000==50000 |
…… | …… |
公式: 位数上数用n表示,e表示位数
10^e-1 * e
方法一:
自己发现规律,然后摸索公式;如上:
class Solution {
public:
int NumberOf1Between1AndN_Solution(int n) {
if(n<=0) return 0;
int count=0;
int ret=0;
int temp=n;
while(temp){//记录位数
temp/=10;
count++;
}
// pow(10,exponent-1)*exponent;
int e=0;
int a=0,b=n;
while(count--){
a=b%10;//a记录每一位的数,从最低位开始
b=b/10;//b记录剩下的数,
//个位含1数,写入。。十位含1数,写入..依次...
if(a>1)
//如果位数,为0,什么都不做,是1,就把前面+位数前面的数字大小再+1,
//大于1,就直接用公式;
ret+=pow(10,e-1)*e*a+pow(10,e);
else if(a==0) {}
else {
int index=pow(10,e);
ret+=pow(10,e-1)*e*a+n%index+1;
}
e++;
}
return ret;
方法二:
网上的,公式也不太明白,仅供参考;
int cnt = 0;
for(int m = 1; m <= n; m *= 10) {
int a = n / m, b = n % m;
cnt += (a + 8) / 10 * m + (a % 10 == 1 ? b + 1 : 0);
}
return cnt;
方法三:
递归查找n-1中1的个数;
int NumberOf1Between1AndN_Solution(int n) {
if(n<=0) return 0;
int num=0;
int i=n;
while(i){
if(i%10==1)
num++;
i/=10;
}
num+=NumberOf1Between1AndN_Solution(n-1);
return num;
}
方法四:
将数字转为字符串,循环遍历查看字符串中‘1’的个数;
int Count(string s){
int num=0;
for(auto &e:s){
if(e=='1')
num++;
}
return num;
}
int NumberOf1Between1AndN_Solution(int n) {
int ret=0;
for(int i=1;i<=n;i++){
ret+=Count(to_string(i));
}
return ret;
方法五:
循环遍历每个数,拆分看每一位是否有1;
int NumberOf1Between1AndN_Solution(int n) {
if(n<=0) return 0;
int ret=0;
for(int i=1;i<=n;i++){//遍历每个数
int temp=i;
while(temp){//循环拆分判断个位是否有1,直到数为0;
if(temp%10==1)
ret++;
temp/=10;
}
}
return ret;
}
以上是关于剑指 Offer JZ31 整数中1出现的次数(从1到n整数中1出现的次数)的主要内容,如果未能解决你的问题,请参考以下文章
剑指 Offer JZ31 整数中1出现的次数(从1到n整数中1出现的次数)
剑指offer(C++)-JZ53:数字在升序数组中出现的次数(算法-搜索算法)