162.Number of Digit One

Given an integer n, count the total number of digit 1 appearing in all non-negative integers less than or equal to n.

For example:
Given n = 13,
Return 6, because digit 1 occurred in the following numbers: 1, 10, 11, 12, 13.

显然不能依次计算每个0--n中每个数中1出现的个数。所以需要去找规律。
      对于0--n中1出现的次数可以分成三部分考虑。假设n为digit位数。
     第一部分:对于digit位数,统计1出现在最高位的情况。如果最高位大于1,则可能有10的n-1次方个,比如2345,1出现在最高位的四位数字有1000个,如果n==1则有后面的数字加1个,比如1234,1出现在最高位的四位数字有235个;
     第二部分:对于digit位数,统计1出现在其他位上的情况。那么需要固定首位first为1--first,在后面digit-1位中选定一个位置为1,其他digit位-2可以任选数字,则first*(digit-1)*10^(digit-2)
     第三部分就是计算digit-1位数。



/**
     * 显然不能依次计算每个0--n中每个数中1出现的个数。所以需要去找规律。
     * 对于0--n中1出现的次数可以分成三部分考虑。假设n为digit位数。
     * 第一部分:对于digit位数,统计1出现在最高位的情况。如果最高位大于1,则可能有10的n-1次方个,比如2345,1出现在最高位的四位数字有1000个,如果n==1则有后面的数字加1个,比如1234,1出现在最高位的四位数字有235个;
     * 第二部分:对于digit位数,统计1出现在其他位上的情况。那么需要固定首位first为1--first,在后面digit-1位中选定一个位置为1,其他digit位-2可以任选数字,则first*(digit-1)*10^(digit-2)
     * 第三部分就是计算digit-1位数。
     */
    public int countDigitOne(int n) {
      
		    int resultNum = 0;
		    if(n<=0){
		    	return 0;
		    }
		    /*个位数返回1出现的次数为1*/
		    if(n<=9){
		    	return 1;
		    }
		    /*把这个数转化为长度字符数组*/
		    String s = n+"";
		    char[] arr = s.toCharArray();
		    int digit = arr.length;
		    /*计算首位的值*/
		    int first = arr[0] - '0';
		    /*计算除了首位之后的整数值:1345*/
		    int other = getInteger(arr,1);
		    /*计算去掉首位时剩下的n-1位中1出现的次数 递归计算1345*/
		    int numerOfn1 = countDigitOne(other);
		    /*计算首位为1的n位整数中1出现的次数*/
		    int numerFirst1 = 0;
		    if(first==1){
		    	numerFirst1 = other+1;//如12345中1在首位的五位数中出现的数字有2346个。
		    }else{//对于首位不为1的len位数来说,1在首位出现的数字有10的(len-1)次方
		    	numerFirst1 = getPower10(digit-1);
		    }
		    /*计算首位不为1的n位整数中1出现的次数,1346 ~ 21345除了第一位为1的情况
* 对于这种情况来说,对于后面的(len-1)位,任意一位固定为1,则其他为可任选,则有(len-1)*(10的(len-1)次方),最后再乘以首位数字。
*/
		    int numerFirstN1 = first*(digit-1)*getPower10(digit-2);
		    /*汇总*/
		    resultNum = numerOfn1 + numerFirst1 + numerFirstN1;
		    return resultNum;
	    }
	 /**
	  *  把数组arr[index]之后的字符组成整数。
	  */
	 int getInteger(char[] arr,int index){
		 int re = 0;
		 int len = arr.length;
		 for(int i=index;i<len;i++){
			 re = re*10 + arr[i]-'0';
		 }
		 return re;
	 }
	 /**
	  * 计算10的ex次方。 
	  */
	 int getPower10(int ex){
		 int re = 1;
		 for(int i=0;i<ex;i++){
			 re = re*10;
		 }
		 return re;
	 }


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值