剑指Offer之从1到n整数中1出现的次数

题目描述

  求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有一、十、十一、十二、13所以共出现6次,可是对于后面问题他就没辙了。ACMer但愿大家帮帮他,并把问题更加广泛化,能够很快的求出任意非负整数区间中1出现的次数。java

基本思路

  当计算右数第$i$位包含的1个数时,一、取第$i$左边(高位)的数字,乘以$10^{i-1}$,获得基础数值a;二、取第$i$位数字计算修正值:算法

  1. 若是大于1,则结果为a+$10^{i-1}$
  2. 若是小于1,则结果为a
  3. 若是等于1,则取第$i$位右边(低位)的数字设为b,则结果为a+b+1

此算法的时间复杂度为$O(log_{10}n)$spa

Java代码

package com.swordOffer.numberOfOne23; import java.util.Scanner; /** * Created by Feng on 2017/5/27. * 求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数? * 为此他特别数了一下1~13中包含1的数字有一、十、十一、十二、13 * 所以共出现6次,可是对于后面问题他就没辙了。 * ACMer但愿大家帮帮他,并把问题更加广泛化,能够很快的求出任意非负整数区间中1出现的次数。 */
public class NumberOfOne { public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (sc.hasNext()) { int inputNum = sc.nextInt(); int result = numberOfOne(inputNum); System.out.println(result); } } private static int numberOfOne(int inputNum) { //统计1的个数
        int count = 0; //表示当前数字
        int curNum = 0; //表示低位
        int lowNum = 0; //表示高位
        int highNum = 0; //表示因子
        int factor = 1; while (inputNum / factor != 0) { // 12345对10取余,至关于将当前数置为个位
            curNum = (inputNum / factor) % 10; lowNum = inputNum % factor; highNum = inputNum / (factor * 10); //若是为0,出现1的次数由高位决定,等于高位数字 * 当前位数
            if (curNum == 0) { //表示10,101的状况
                count += factor * highNum; } else if (curNum == 1) { //若是为1,出现1的次数由高位和低位决定,高位*当前位+低位+1
                count += factor * highNum + lowNum + 1; } else { //若是大于1,出现1的次数由高位决定, //高位数字+1* 当前位数
                count += factor * (highNum + 1); } factor *= 10; } return count; } }
相关文章
相关标签/搜索