【剑指offer】44. 数字序列中某一位的数字

题目描述

在这里插入图片描述

// 44. 数字序列中某一位的数字


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

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

题解

// 1.先求n所在的数字属于几位数,2.后求n所在的数字num,3.最后求n在数字num的第几位
// 如n=11,我们将
// 1:先求n所在的数字属于2位数
// 2:后求n所在的数字为10,
// 3:最后求得n在数字10的第二位,即目标为数字0。

// 力扣
// 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
// 内存消耗:35.3 MB, 在所有 Java 提交中击败了33.22%的用户
class Solution {
    public int findNthDigit(int n) {
		// 位数记录,如11为2位数,123为3位数。初始化digit为1
		int digit = 1;  
		// 当前以位数digit所开始的数字,2位数开始的数字为10,1位数
		// 开始的数字为1(0不算1位数)
		long start = 1;  
		// 在当前位数digit下包含的数字数量。由于位数digit初始化为1,
		// 所以位数为1的数字总共有1 2 3 4 5 6 7 8 9,共9个数字。
		long count = 9;
		// 先求n所在的数字num的位数digit
		// 如果位数数字总数count少于n,执行循环
		while (count < n) {  
			n -= count;   // n减去当前位数数字总数count,若n=15,更新为n=15-9=6
			digit++;      // 位数更新
			start *= 10;  // 位数digit开始的数字start根据位数进行更新
			count = 9 * start * digit;  // count根据start和digit进行更新
		}
		// 若n=15更新为了n=6。位数digit同时可以理解为所在位数区间内
		// 所有数字的长度,digit=2,说明所在位数区间内所有数字长度都为2,
		// 而n-1表示从start(start=10)数字第一位开始,到达n=6位置的数位长度
		// (所经历的位)即1->0->1->1->1->2,长度为5。
		// 那么(n-1)/digit即可得到数字本身从start开始,在位数区间的数字长度(所经历的数)
		// 即10->11->12,长度为2。此时再加上start即可得到n所在的数字num
		long num = start + (n - 1) / digit;
		// 求n所在数字的第几位
		// n-1表示从start(start=10)数字第一位开始,到达n=6位置的数位长度
		// 我们直接看这个长度能不能被digit整除即可
		int i = (n - 1) % digit;
		return Long.toString(num).charAt(i) - '0';
    }
}

猜你喜欢

转载自blog.csdn.net/fisherish/article/details/113271675