题目描述:求从1 到 n 中1出现的次数

夏都:首先请大家看一下以下的几个输出结果
0 --- 0
9 --- 1
99 --- 20
999 --- 300
9999 --- 4000
99999 --- 50000
999999 --- 600000
9999999 --- 7000000
对于一个任意的数,从1到n中的次数,比如n为abcdefg和从0000000abcdefg中1出现的次数一样,即输入结果为n位数,则对0n的每个数左边补0使其位数和n的位数相匹配。
对于从1到n中出现的次数,我们不妨先考虑一些特殊的值
一位数的范围09,这其中1出现1次
两位数的范围0
99可以视为0099,其中个位和十位分别在09的之间变化,对于0099,忽略掉十位的影响,个位中1出现的次数为:10*1即10次,接下来考虑十位的影响,十位不为1时,对结果无影响,十位为1时,结果+1,十位为1共出现10次,因此099中1出现的个数为20次
接下来考虑0999,忽略掉百位的影响,十位都是从0099进行变化,因此,十位和个位中出现的次数为2010即200次,接下来考虑百位的影响,百位不为1时,对结果无影响,百位为1的数共出现100次,因此0~~999中1出现的次数为200+100==300次依次进行递推可以得到,对于0到9···9(n个9) 可以得出结论 1的出现次数为图片说明
接下来我们考虑一个输入为abcdefg,我们可以把这个数分为两个部分0000000到(a-1)999999, 和a000000到abcdefgh,接下来考虑一下a的值
a为1时,0000000到(a-1)999999即可用上面的公式计算得出,对于a000000到abcdefgh,考虑a所在位的影响,a一共出现bcdefgh+1次,接下来,忽略a所在位的影响,剩下的数和从000000到bcdefgh的结果一致,递归调用即可,故此,当a==1时,最终结果= 600000 + bedefgh +1 + 递归计算(bcdefgh)
当a不为1时,对于0000000到(a-1)999999,忽略掉a所在位的影响,其余位从0到999999循环a次,结果为
a
600000,由于a>1,所以结果要加上1000000,1在a的位共出现次,接下来考1000000虑a000000到abcdefgh,由于a!=1,所以其结果=递归计算(bcdefgh),故此,a不为1时候的计算结果= a*600000 + 1000000 + 递归计算(bcdefgh)
总结尾,对于一个n位数(,首位为1时,结果为图片说明
首位不为1时,设首位为x,则结果为 图片说明

public static int NumberOf1Between1AndN_Solution(int n) {

        if( n == 0 || n == 1 )    return n;
        if(n>1&&n<10)             return 1;
        String num = String.valueOf(n);
        if( num.charAt(0) == '1' ) {
            return (int) ((num.length()-1) * Math.pow(10, num.length()-2) + Integer.parseInt(num.substring(1)) + 1 + NumberOf1Between1AndN_Solution(Integer.parseInt(num.substring(1))));
        }else {
            return (int) ((num.charAt(0) - '0') * (num.length()-1) * Math.pow(10, num.length()-2) + Math.pow(10, num.length()-1) + NumberOf1Between1AndN_Solution(Integer.parseInt(num.substring(1))));
        }
    }
第一次写,没什么经验,希望大家多提意见。