求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有一、十、十一、十二、13所以共出现6次,可是对于后面问题他就没辙了。ACMer但愿大家帮帮他,并把问题更加广泛化,能够很快的求出任意非负整数区间中1出现的次数。java
当计算右数第$i$位包含的1个数时,一、取第$i$左边(高位)的数字,乘以$10^{i-1}$,获得基础数值a;二、取第$i$位数字计算修正值:算法
此算法的时间复杂度为$O(log_{10}n)$spa
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; } }