从1到n整数中1出现的次数

Posted tianzeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从1到n整数中1出现的次数相关的知识,希望对你有一定的参考价值。

题目

输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。例如输入12,从1到12这些整数中包含1的数字有1,10,11和12,1一共出现了5次。

思路

  1.先根据数组的最高位计算1出现的次数 

  • 如果只有一位数且该为是0,返回0 
  • 如果只有一位数且该为大于0,则1出现的次数只有1次
  • 如果最高位数字大于1,则最高位1出现的次数是10^len-1次方 
  • 如果最高位数字不大于1,1出现的次数是除最高位所有的数字+1次 

  2.其他位1出现的次数:最高位不变,固定其他一位,剩余的位数全排列 

  3.去除最高位,递归求得依次剩余的位数 

#include <iostream>
#include <sstream>
#include <cmath>
using namespace std;

class Solution
{
    public:
        int num_of_one(string s);
        int digit(const unsigned int n);
};
int Solution::num_of_one(string s)
{
    if(s.empty()||s.size()<=0||*s.begin()<=0||*(--s.end())>9)
        return 0;
    
    //1.先根据数组的最高位计算1出现的次数 
    int first=*s.begin()-0;
    unsigned int len=s.size();
    if(len==1&&first==0) //如果只有一位数且该为是0,返回0 
        return 0;
    else if(len==1&&first>0)//如果只有一位数且该为大于0,则1出现的次数只有1次 
        return 1;
    
    int num_first_digit=0;
    if(first>1)//如果最高位数字大于1,则最高位1出现的次数是10^len-1次方 
        num_first_digit=digit(len-1);
    else if(first==1)//如果最高位数字不大于1,1出现的次数是除最高位所有的数字+1次 
        num_first_digit=*(++s.begin())-0+1;
    
    //2.其他位1出现的次数:最高位不变,固定其他一位,剩余的位数全排列 
    int num_other_digit=first*(len-1)*digit(len-2);
    s.erase(s.begin());
    //3.去除最高位,递归求得依次剩余的位数 
    int num_recursive=num_of_one(s);
    
    return num_first_digit+num_other_digit+num_recursive;
}
int Solution::digit(const unsigned int n)
{
    return (int)pow(10,n);
} 
int main()
{
    long n;
    cin>>n;
    
    stringstream ss;
    ss<<n; 
    Solution s;
    cout<<s.num_of_one(ss.str())<<endl;
    return 0;
}

 

以上是关于从1到n整数中1出现的次数的主要内容,如果未能解决你的问题,请参考以下文章

剑指offer(四十)之整数中1出现的次数(从1到n整数中1出现的次数)

剑指Offer对答如流系列 - 从1到n整数中1出现的次数

剑指offer-整数中1出现的次数(从1到n整数中1出现的次数)

整数中1出现的次数(从1到n整数中1出现的次数)

剑指offer整数中1出现的次数(从1到n整数中1出现的次数)

整数中1出现的次数(从1到n整数中1出现的次数)