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


comments: true
difficulty: 中等
edit_url: https://github.com/doocs/leetcode/edit/main/lcof/%E9%9D%A2%E8%AF%95%E9%A2%9844.%20%E6%95%B0%E5%AD%97%E5%BA%8F%E5%88%97%E4%B8%AD%E6%9F%90%E4%B8%80%E4%BD%8D%E7%9A%84%E6%95%B0%E5%AD%97/README.md

面试题 44. 数字序列中某一位的数字

题目描述

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

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

 

示例 1:

输入:n = 3
输出:3

示例 2:

输入:n = 11
输出:0

 

限制:

  • 0 <= n < 2^31

注意:本题与主站 400 题相同:https://leetcode.cn/problems/nth-digit/

解法

方法一:数学

【LeetCode力扣刷题 | 剑指Offer题解合集 | 画解算法思路Python3或C++代码实现】 https://www.bilibili.com/video/BV1CK411c7gx/?p=39&share_source=copy_web&vd_source=ed4a51d52f6e5c9a2cb7def6fa64ad6a
在这里插入图片描述

位数为 k k k 的最小整数和最大整数分别为 1 0 k − 1 10^{k-1} 10k1 1 0 k − 1 10^k-1 10k1,因此 k k k 位数的总位数为 k × 9 × 1 0 k − 1 k \times 9 \times 10^{k-1} k×9×10k1

我们用 k k k 表示当前数字的位数,用 c n t cnt cnt 表示当前位数的数字的总数,初始时 k = 1 k=1 k=1, c n t = 9 cnt=9 cnt=9

每次将 n n n 减去 c n t × k cnt \times k cnt×k,当 n n n 小于等于 c n t × k cnt \times k cnt×k 时,说明 n n n 对应的数字在当前位数的数字范围内,此时可以计算出对应的数字。

具体做法是,首先计算出 n n n 对应的是当前位数的哪一个数字,然后计算出是该数字的第几位,从而得到该位上的数字。

时间复杂度 O ( log ⁡ 10 n ) O(\log_{10} n) O(log10n),空间复杂度 O ( 1 ) O(1) O(1)。其中 n n n 为给定的数字。

Python3
class Solution:
    def findNthDigit(self, n: int) -> int:
        k, cnt = 1, 9
        # 1) K:确定是 几位数
        while k * cnt < n: #9 9*10*2 9*100*3 ...
            n -= k * cnt
            k += 1
            cnt *= 10
        # 2)start: 10 ** (k - 1) -> 确定 几位数范围内 对应 具体那个数
        num = 10 ** (k - 1) + (n - 1) // k
		
		# 3)在具体那个数 中 取对应位的数
        idx = (n - 1) % k # 计算对应的位
        return int(str(num)[idx])
Java
class Solution {
    public int findNthDigit(int n) {
        int k = 1, cnt = 9;
        while ((long) k * cnt < n) {
            n -= k * cnt;
            ++k;
            cnt *= 10;
        }
        int num = (int) Math.pow(10, k - 1) + (n - 1) / k;
        int idx = (n - 1) % k;
        return String.valueOf(num).charAt(idx) - '0';
    }
}
C++
class Solution {
public:
    int findNthDigit(int n) {
        int k = 1, cnt = 9;
        while (1ll * k * cnt < n) {
            n -= k * cnt;
            ++k;
            cnt *= 10;
        }
        int num = pow(10, k - 1) + (n - 1) / k;
        int idx = (n - 1) % k;
        return to_string(num)[idx] - '0';
    }
};
Go
func findNthDigit(n int) int {
	k, cnt := 1, 9
	for k*cnt < n {
		n -= k * cnt
		k++
		cnt *= 10
	}
	num := int(math.Pow10(k-1)) + (n-1)/k
	idx := (n - 1) % k
	return int(strconv.Itoa(num)[idx] - '0')
}
JavaScript
/**
 * @param {number} n
 * @return {number}
 */
var findNthDigit = function (n) {
    let k = 1,
        cnt = 9;
    while (k * cnt < n) {
        n -= k * cnt;
        ++k;
        cnt *= 10;
    }
    const num = Math.pow(10, k - 1) + (n - 1) / k;
    const idx = (n - 1) % k;
    return num.toString()[idx];
};
C#
public class Solution {
    public int FindNthDigit(int n) {
        int k = 1, cnt = 9;
        while ((long) k * cnt < n) {
            n -= k * cnt;
            ++k;
            cnt *= 10;
        }
        int num = (int) Math.Pow(10, k - 1) + (n - 1) / k;
        int idx = (n - 1) % k;
        return num.ToString()[idx] - '0';
    }
}
Swift
class Solution {
    func findNthDigit(_ n: Int) -> Int {
        var n = n
        var k = 1
        var count = 9

        while k * count < n {
            n -= k * count
            k += 1
            count *= 10
        }

        let num = Int(Double(10).power(Double(k - 1))) + (n - 1) / k
        let idx = (n - 1) % k
        let numString = String(num)
        let char = numString[numString.index(numString.startIndex, offsetBy: idx)]

        return char.wholeNumberValue!
    }
}

extension Double {
    func power(_ exponent: Double) -> Double {
        return pow(self, exponent)
    }
}
  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值