链接
给定一个整数n,返回从1到n的数字中1出现的个数。

import java.util.Scanner;

public class Main {

    private static long[] getLenAndBase(long n) {
        long len = 1;
        long base = 1;
        while (base <= n / 10) {
            base *= 10;
            len++;
        }
        return new long[]{len, base};
    }

    private static long solve(long n) {
        if (n == 0) {
            return 0;
        }

        if (n <= 9) {
            return 1;
        }

        long[] lenAndBase = getLenAndBase(n);

        long len = lenAndBase[0];
        long base = lenAndBase[1];

        // 3998
        // [1, 998]
        // [999, 1998]
        // [1999, 2998]
        // [2999, 3998]

        long first = n / base;
        long firstOneNum = first == 1 ? n % base + 1 : base;
        long otherOneNum = first * (len - 1) * (base / 10);

        return firstOneNum + otherOneNum + solve(n % base);
    }

    private static long solvePlus(long n) {
        long ret = 0;

        long[] lenAndBase = getLenAndBase(n);

        long len = lenAndBase[0];
        long base = lenAndBase[1];

        while (n != 0) {
            // 3998
            // [1, 998]
            // [999, 1998]
            // [1999, 2998]
            // [2999, 3998]

            long first = n / base;
            long firstOneNum = first == 1 ? n % base + 1 : base;
            long otherOneNum = first * (len - 1) * (base / 10);
            ret += firstOneNum + otherOneNum;

            n %= base;
            len --;
            base /= 10;
        }

        return ret;
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            long n = in.nextLong();
            System.out.println(solvePlus(n));
        }

    }
}
心之所向,素履以往 生如逆旅,一苇以航