每次做题的时候都会发觉自己真是菜得一逼,这不这道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。
网友评论