1.题目
数字以 0123456789101112131415… 的格式作为一个字符序列,在这个序列中第 2 位(从下标 0 开始计算)是 2 ,第 10 位是 1 ,第 13 位是 1 ,以此类题,请你输出第 n 位对应的数字。
2.解法
2.1 题目框架
public class Solution {
public int findNthDigit (int n) {
}
}
2.2 解法1
对于10以内的数,对应的位置就是n
否则考虑,二位数会占2个位置,所有的两位数占据902个位置, 三位数占3个数位,9003 个位置。依次类推。于是我们实现了一个long count(int level)
方法,根据位数计算占据的的位置。
那么对于 n 是这个序列的下标,那么它是什么数?我们首先要明确n是几位数?那么就用m -= cnt * level;
就可以找到是几位数。然后知道了是几位数就简单了。
1、int start = (int) Math.pow(10,level-1);
,表示起点。
2、int more = m/level; int offset = m%(level);
表示经过了拿哪几个数字,目前停在那个数字的第几位。
3、使用String.valueOf(start+more).charAt(offset)-'0'
求解。
public int findNthDigit(int n) {
if(n<10) return n;
// write code here
n-=10;
int level = 2;
int m = n;
while (true) {
long cnt = count(level);
if ( cnt * level > m) break;
m -= cnt * level;
level++;
}
int start = (int) Math.pow(10,level-1);
int more = m/level;
int offset = m%(level);
return String.valueOf(start+more).charAt(offset)-'0';
}
private long count(int level) {
if (level == 2) return 90;
return 10 * count(level - 1);
}
2.3 解法2
与解法1类似。
public int findNthDigit2 (int n) {
// write code here
if(n < 10)
return n;
n -= 10;
int digit = 2;
long num = 10, sum = 90;
while(n - digit * sum >= 0) {
n -= digit * sum;
digit++;
sum *= 10;
num *= 10;
}
int div = n / digit;
int mod = n % digit;
long now = num + div;
return String.valueOf(now).charAt(mod) - '0';
}
总结
这个n 是下标,这道题就是要定位 n 在哪个区间。
我们先定位是几位数,比如是3位数,那么就是从100开始的,然后计算偏移量。最后相加即可。
算法系列在github上有一个开源项目,主要是本系列博客的demo代码。https://github.com/forestnlp/alg
如果您对软件开发、机器学习、深度学习有兴趣请关注本博客,将持续推出Java、软件架构、深度学习相关专栏。
您的支持是对我最大的鼓励。