400. Nth Digit

每次做题的时候都会发觉自己真是菜得一逼,这不这道easy题就没做出来。

题目描述

在数字队列1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11....的无穷队列里找到第nth个数,比如第11个数是数字0。

我(超)的(时)解法

public class Solution {
    public static int findNthDigit(int n) {
        if (n <= 9) {
            return n;
        } else {
            int x = 0, i = 1;
            while (x <= n) {
                x += count(i);
                if (x == n) {
                    break;
                }
                if (x <= n) {
                    i++;
                }
            }
            int off = x - n;

            if (off != 0) {
                return findNthDigitInNum(i, off);

            } else {
                return (i % 10);
            }

        }

    }

    public static int count(int num) {
        int count = 1;
        while (num / 10 != 0) {
            num /= 10;
            count++;
        }
        return count;
    }

    public static int findNthDigitInNum(int num, int nth) {
        int x = 0, s = 10;
        for (int i = 0; i <= nth; i++) {
            x = num % 10;
            num /= 10;
        }

        return x;
    }
}

思路蛮简单,定一个变量初始值为0,每次加上新的数字的长度,最后如果超出了给定的结果,就退回若干位去找该位上的数字,如果刚好等于给定的长度,对当前的数字求最低位。
在测试用例1000000000的时候超时了....没想到什么好的解决方法,又无耻的去看了下Top Solution

Top Solution

Top Solution里的解法跟我的解法思想上是类似,但是他用了很不错的技巧

public int findNthDigit(int n) {
        int len = 1;
        long count = 9;
        int start = 1;

        while (n > len * count) {
            n -= len * count;
            len += 1;
            count *= 10;
            start *= 10;
        }

        start += (n - 1) / len;
        String s = Integer.toString(start);
        return Character.getNumericValue(s.charAt((n - 1) % len));
    }

我的解法里是一个一个叠加数字的长度,他则是把相同位数的数字一次性减掉,这里效率高了很多。再看start += (n-1) / len,这里的n-1是为了不跳到下一个数字去,这个语句可以得出满足条件的最后一个数字是什么。(n-1) % len这个表达式的作用是求出最后一个数字是第几位上的,这里的n-1是因为s.charAt()的开始下标是0。
举个列子,假设输入:n=11,那么执行上面这个表达式时(2-1) % 2,即返回最大数字的第二位,此时start的值为10,所以结果为0。

你可能感兴趣的:(400. Nth Digit)