剑指offer-32从1到n整数出现1的次数

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

将输入的整数分为2部分,以后(n-1)位为分割点分为2部分,如21345分为1到1345和1346到21345,对第一部分递归调用算法,对后面的部分进行数学分析可以得出其中1的个数。首先最高位1出现的次数分为2种情况从1345到21345最高位出现了10000次为10000到19999,若最高位是1如12345,则最高位出现为10000到12345,共2346次。除最高位剩余段根据最高位的数字可分为多个段,每段的某一位为1时,其余各位能够为0~9,1出现总共次数为(最高位数字)*(剩余位的个数)*10^(剩余位个数-1)。代码如下:

class Solution {
public:
    int NumberOf1Between1AndN_Solution(int n)
    {
       	//n的第一位数字
        int firstposition=n;
        int length=1;
        while(firstposition>=10)
        {
            tmp=tmp/10;
            length++;
        }
        if(n==0)
            return 0;
        if(length==1&&firstposition>1)
            return 1;
        
        int m=n-firstposition*PowerBase10(length-1);
        //记录最高位出现1的次数
        int numberfirst = 0;
        if(tmp>1)
            numberfirst = PowerBase10(length-1);
        else if(tmp==1)    
            numberfirst = m+1;
        //除了最高位其他位出现1的次数
        int numberother = firstposition*(length-1)*PowerBase10(length-2);
        //剩下的数字递归求解。
        int numberRecursive = NumberOf1Between1AndN_Solution(m);
        return numberfirst + numberother + numberRecursive;
    }
    int PowerBase10(int n)
    {
        int result = 1;
        for(int i = 0; i<n; ++i)
            result*=10;
        return result;
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值