剑指offer第32题JS算法:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。例如输入12,从1到12这些整数中包含1的数字有1,10,11和12,1一共出现了5次

版权声明:【原创】GitHub:https://github.com/susuGirl,微信公众号:fuxiaodexing,博客:https://blog.csdn.net/weixin_41845146 https://blog.csdn.net/weixin_41845146/article/details/84786350

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

这是我某一次去朋友公司面试试水时出的面试题,结果给我五分钟我写了个for循环的方法,被狠狠鄙视/哭笑不得

结果回来后好奇就跟同事一起看了看这道题发现也挺有意思的

//参数n为中点数字,且为整数
function result(n){
    //count表示观察的值(这里为1)出现的次数,base表示当前循环权重,round表示当前要进入循环的数和当前数的周期(高位)
    let count = 0,base = 1,round = n
    //当前要进入循环的数不小于1时,执行循环
    while(round>=1){
//求出当前数基数
        let weight = round % 10
//求出当前数周期(向下取整),并用作下一轮循环的数
        round = Math.floor(round / 10)
//当基数小于1(即为0)时,出现次数为当前周期乘以当前权重
if(weight < 1){
            count += round * base
//当基数大于1时,出现次数为当前周期乘以当前权重再加上额外的一次权重
}else if(weight > 1){
            count += (round + 1) * base
//当基数等于1时,出现次数为当前周期乘以当前权重再加上(基数低一位的数值加1,加1是因为从0开始计数)
        } else if(weight === 1){
            count += round * base + (n%base)+1
        }
//本次循环完毕后权重乘以10,实现按位数循环,达到O(logn)的复杂度
        base *= 10
    }
    //返回最终的出现总次数
    return count
}
改良版:
function result(n,m){
    let count = 0,base = 1,round = n
    while(round>=m){
        let weight = round % 10
        round = Math.floor(round / 10)
        if(weight > m){
            count += (round + 1) * base
        } else if(weight === m){
            count += round * base + (n%base)+1
        } else{
            count += round * base
        }
        base *= 10
    }
    return count
}
n为最大整数,m为要观察次数的数字

猜你喜欢

转载自blog.csdn.net/weixin_41845146/article/details/84786350