1到n中“1”出现的次数

根据剑指offer的思路可以分为以下三个步骤(数字n是k位,数字n最高位是h):

1. 计算最高位出现1的次数。若最高位为1,则最高位出现1的次数为除最高位以外的数值+1。例如1132,最高位出现1的次数为132+1=133。

2. 剩余情况划分为h+1段,对于其中的h段,计算(k-1)位1出现的次数。将数字划分h+1段,除去第一段外的h段都可以用排列组合计算。例如2136,可以分为1-136,137-1136,1137-2136,需要计算后两段个十百位1的个数。计算公式为:h*(k-1)*10^(k-2),含义为选中k-1位中的任意一位设置为1,其余位数自动变换。

3. 将2中的第1段进行迭代。

三个部分的count求和,得到answer。

    public static int NumberOf1Between1AndN_Solution(int n){
        //异常输入单独处理
        if(n<=0) return 0;
        //临时变量
        int nTmp=n;//n的替身
        int numberLength=0;//n的位数
        int highestBit=0;//n的最高位
        //三个count,分别代表最高位、除最高位的其它位、第一段分别出现1的个数
        int highestBitCount=0,otherBitCount=0,firstPhaseCount=0;
        //计算临时变量
        while(nTmp!=0){
            highestBit=nTmp%10;//记录最高位
            nTmp/=10;
            numberLength++;//计算n的位数
        }
        //只有一位的数字单独处理
        if(numberLength==1) return 1;
        //最高位1个数计算
        if(highestBit==1){
            highestBitCount=n-highestBit*(int)(Math.pow(10,numberLength-1)+0.5)+1;
        }
        else if(highestBit>1){
            highestBitCount=(int)(Math.pow(10,numberLength-1)+0.5);
        }

        //其它位1个数计算
        if(numberLength>1){
            otherBitCount=highestBit*(numberLength-1)*(int)(Math.pow(10,numberLength-2)+0.5);
        }
        //第一段迭代
        firstPhaseCount=NumberOf1Between1AndN_Solution(n-highestBit*(int)(Math.pow(10,numberLength-1)+0.5));
        //最终结果
        return highestBitCount+otherBitCount+firstPhaseCount;
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值