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

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

解题思路:

  1. 解法一:循环依次对每一个1~n之间的数求模,若模为1则计次,最终返回1出现的次数。复杂度高O(n*longN).
  2. 解法二:从数字规律着手明显提高时间效率的解法O(logn)

    测试用例:

int main(){
    //输入数组
    int number = 12;
    //结果
    int res = NumberOf1Between1AndN(number);
    std::cout << "Number of one in N is: " << res;

    return 0;
}

函数实现:

//辅助函数
int PowerBase10(unsigned int n){
    int result = 1;
    for(unsigned int i = 0; i < n; ++i)
        result *= 10;
    return result;
}
//函数实现,利用字符串方便编程
//核心函数
int NumberOf1(const char *strN){
    if(!strN || *strN < '0' || *strN > '9' || *strN == '\0')
        return 0;
    int first = *strN - '0';  //第一位
    unsigned int length = static_cast<unsigned int>(strlen(strN));  //字符串长度

    if(length == 1 && first == 0)
        return 0;  //如果长度为1 && 第一位等于0,那么1出现的次数必然为0
    if(length == 1 && first > 0)
        return 1;  //如果长度为1 && 第一位大于0, 那么1必然出现1次

    //假设strN是“21345”
    //numFirstDigit是数字10000~19999的第一个位中的数目
    int numFirstDigit = 0;
    if(first > 1)
        numFirstDigit = PowerBase10(length - 1);  //直接求出共有多少个1
    else if(first == 1)
        numFirstDigit = atoi(strN + 1) + 1; //直接转化为次数
    //numOtherDigits是1346~21345除了第一位之外的数位中的数目
    int numberOtherDigits = first * (length - 1) * PowerBase10(length - 2);
    //numRecursive是1~1345中的数目
    int numRecursive = NumberOf1(strN + 1);

    return numFirstDigit + numberOtherDigits + numRecursive;
}
//接口函数
//先把数字转换成字符串
int NumberOf1Between1AndN(int n){
    if(n <= 0)
        return 0;
    char strN[50];
    sprintf(strN, "%d", n);  //把整个数字转换成字符串
    return NumberOf1(strN);  //核心算法
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值