在1-n中1出现的次数(微软等IT公司面试一百题)

39 篇文章 0 订阅

因为自己想的思路和网络上广泛的思路不一样,所以写一下我的思路,验证结果是正确的


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

(Google面试题目)


用两个数字简述我的思路 例如输入为 7111


从1-7111可以分解成1-6999 和 111

这个数字的第一个数是7 大于1,所以从1000-1999这些数字里都多了一个1


所以NumOfOnes(7111) = NumOfOnes(111) + 7 * NumOfOnes(999) + 1000

之后求811和999可以用递归的方法。


不过需要注意的是,当第一个数字为1的时候,例如111,算法要执行另外一个分支

111可以分为1-99,100-111,100-111里面含有的1个个数是 (111-100 + 1) + NumOfones(11)

所以最后算法写成

NumOfOnes(111) = NumOfOnes(99) + 111 - 100 + 1 + NumOfOnes(11)


最后写程序如下: 

void ParseNumber(int num, int &nDigits, int &nFirst, int &nOthers, int &nMaxDigits)
{
    nDigits = 0;
    int origNum = num;
    while(num >= 10)
    {
        num /= 10;
        nDigits ++;
    }
    nFirst = num;
    nMaxDigits = pow(10.0,nDigits) ;
    nOthers = origNum - nMaxDigits * nFirst;
    nMaxDigits -= 1;

}
int GetNumOfOnes(int N)
{
    if( N == 0)
    {
        return 0;
    }
    if( N < 10 )
    {
        return 1;
    }
    int nDigits, nFirst, nOthers, nMaxDigits;

    ParseNumber(N, nDigits, nFirst, nOthers, nMaxDigits);

    if( nFirst == 1)
    {
        return GetNumOfOnes(nMaxDigits) + nOthers + 1 + GetNumOfOnes(nOthers);
    }
    else
    {
        return pow(10.0, nDigits) + (nFirst) * GetNumOfOnes(nMaxDigits) + GetNumOfOnes(nOthers);
    }

}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值