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

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

https://www.nowcoder.com/practice/bd7f978302044eee894445e244c7eee6?tpId=13&&tqId=11184&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

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

剑指offer31
图片说明
1、暴力--直接双重循环
时间复杂度:O(n*m) 空间复杂度:O(1)

2、找规律,计数
//找规律:
// 1、个位上1出现的频率,从1开始,每10个数出现1次,每次出现持续1个数
// 2、10位上1出现的频率,从10开始,每100个数出现1次,每次出现持续10个数
// 3、百位上1出现的频率,从100开始,每1000个数出现1次,每次出现持续100个数
时间复杂度:O(m) m位数字n的位数,eg:11两位长度 空间复杂度:O(1)

个人调试代码

class Solution {
public:
    //找规律:
    //  1、个位上1出现的频率,从1开始,每10个数出现1次,每次出现持续1个数
    //  2、10位上1出现的频率,从10开始,每100个数出现1次,每次出现持续10个数
    //  3、百位上1出现的频率,从100开始,每1000个数出现1次,每次出现持续100个数
    int NumberOf1Between1AndN_Solution(int n) {
        int len=0;//统计n的位数长度,比如:11两位长度
        int cur=n;
        int count=0; //统计1个数
        while(cur)
        {
            cur/=10;
            ++len;
        }
         int digit=1; //位数和出现一次持续个数 初始个位1,每次出现持续一次
         int frq=10;  //出现频率,初始个位10个数出现一次
        for(int i=0;i<len;i++)
        {
            count+=n/frq*digit; //可以确定的出现次数
            //下面处理最后一次出现,最后一次出现不确定出现多少次的问题,可能0,digit,x-digit+1次
            int num=0;
            if(n%frq>=digit) //出现但不确定出现是否digit次,顶多digit次
                num=n%frq-digit+1;
            num=num>digit?digit:num;
            count+=num;
            digit*=10;
            frq*=10;
        }
        return  count;
    }
};
全部评论

相关推荐

牛客263158796号:我领羊一面后十天不挂也不推进 今天问hr说等前序的第一批意向发完看情况再看是否推进
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务