44题-数字序列中某一位的数字

1 题目描述

数字以0123456789101112131415…的格式序列化到一个字符序列中。在这个序列中,第5位(从下标0开始计数)是5,第13位是1,第19位是4,等等。

请写一个函数,求任意第n位对应的数字。

示例1:

输入:n = 3
输出:3

示例2:

输入:n = 11
输出:0

2 解题思路

  1. 将101112…中的每一位称为数位,记为n;
  2. 将10,11,12,…称为数字,记为num;
  3. 数字10是一个两位数,称此数字的位数为2,记为digit;
  4. 每digit位数的起始数字(即:1,10,100,…),记为start。

在这里插入图片描述
观察上表,可推出各digit下的数位数量count的计算公式:
c o u n t = 9 × s t a r t × d i g i t count=9\times start \times digit count=9×start×digit
根据以上分析,可将求解分为三步:

  1. 确定n所在数字的位数,记为digit;
  2. 确定n所在的数字,记为num;
  3. 确定n是num中的哪一数位,并返回结果。

1. 确定所求数位的所在数字的位数
如下图所示,循环执行n减去一位数、两位数、…的数位数量count,直至 n ≤ c o u n t n \leq count ncount时跳出。

由于n已经减去了一位数、两位数、…、(digit-1)位数的数位数量count,因而此时的n是从起始数字start开始计数的。

int digit = 1, start = 1, count = 9;
while (n > count) {
    
    
	n -= count;
	start *= 10;
	digit += 1;
	count = 9 * start * digit;
}

**结论:**所求数位1)在某个digit位数中;2)为从数字start开始的第n个数位。

在这里插入图片描述
2. 确定所求数位所在的数字
如下图所示,所求数位在从数字start开始的第[(n-1)/digit]个数字中(start为第0个数字)。

num = start + (n - 1) / digit;

结论:
所求数位在数字num中。
在这里插入图片描述
3. 确定所求数位在num的哪一数位
如下图所示,所求数位为数字num的第 ( n − 1 ) % d i g i t (n-1) \% digit (n1)%digit位(数字的首个数位为第0位)。

s = Integer.toString(num) //转化为String
res = (int)s[(n-1)%digit]; //获得num的第(n-1)%digit个数位,并转化位int

结论: 所求数位是res。

在这里插入图片描述

class Solution {
    
    
    public int findNthDigit(int n) {
    
    
        int digit = 1;
        long start = 1, count = 9;
        while (n > count) {
    
    
            n -= count;
            start *= 10;
            digit += 1;
            count = 9 * digit * start;
        }
        long num = start + (n - 1) / digit;
        return Long.toString(num).charAt((n - 1) % digit) - '0';
    }

}

复杂度分析:

  • 时间复杂度 O(logn) : 所求数位 n 对应数字 num 的位数 digit 最大为 O(logn) ;第一步最多循环 O(logn) 次;第三步中将 num 转化为字符串使用 O(logn) 时间;因此总体为 O(logn) 。
  • 空间复杂度 O(logn) : 将数字 num 转化为字符串 str(num) ,占用 O(logn) 的额外空间。

猜你喜欢

转载自blog.csdn.net/qq_41242680/article/details/112977982
今日推荐