[数学:数位] 剑指 Offer 44. 数字序列中某一位的数字

177 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情

每日刷题 2022.08.09

题目

  • 数字以0123456789101112131415…的格式序列化到一个字符序列中。在这个序列中,第5位(从下标0开始计数)是5,第13位是1,第19位是4,等等。
  • 请写一个函数,求任意第n位对应的数字。

示例

  • 示例1
输入: n = 3
输出: 3
  • 示例2
输入: n = 11
输出: 0

提示

  • 0 <= n < 2^31

解题思路

  • 分析题目含义:也就是从0开始将后面的数字按照顺序,依次拼接在后面,形成一个数字序列。现在要求给我们一个数值n,返回这个数字序列中第n位的数字。
  • 通过分析:一位数有10个,二位数有90个,三位数有900个,四位数有9000个.....可以看出来,如果不将一位数的0计入,那么一位数、二位数、三位数、四位数等就会呈现规律。(那么为什么不计入一位数的0呢?因为一位数的0,在二位数的时候,是不能够作为二位数的开头,如果作为二位数的开头,就不是一个有效的二位数字了,如04,因此不计入。)
  • 分析到这里:
    • 目前可以知道:第n个数是几位数,记为:digit
    • 未知:是几位数中的第几个数,记为:num
    • 未知:第几个数中的第几位即:数位,记为:res(也就是最终的结果)

详细的分析(三步)

  • 计算第n个数是几位数:通过不断的减去每一个位数所包含的数位,来找到当前的n是处于几位数digit的范围内.
  • 计算是第几个数: 找到digit之后还需要判断是哪个数,因为n是从0开始计数的,而我们为了方便,计算的时候是从并没有将0计入。因此需要将n - 1才是当前的真正的计数值。接下来只需要整除digit,就可以求出是第几个数了。
  • 计算是第几个位数:现在已知是几位数和几位数中的第几个数,还需要求解是这个数的第几位,因此需要使用模运算,让(n - 1) % digit就可以得到是第几位,这样就获得了答案,直接返回即可。

新学的函数

  • charAt()根据当前的下标返回字符串中对应的字符
  • 当然不会这个函数也可以用其他的方法实现,比如说截取字符串的方法。

AC代码

/**
 * @param {number} n
 * @return {number}
 */
var findNthDigit = function(n) {
  // 1位数:10个 2位数:90个 3位数:900个 ,4位数:9000个....
  let digit = 1, start = 1, count = 9;
  // 计算出来当前的位数和开始
  if(n > 0 && n < 9) return n;
  while(n > count) {
    n -= count;
    digit++;
    start = start * 10;
    count = 9 * start * digit;
  }
  // console.log('start:::', digit, n, count, start)
  // 计算n是在哪个数字
  let num = start + Math.floor((n - 1) / digit);
  // console.log(num)
  let idx = (n - 1) % digit;
  return (num + '').charAt(idx);
};