《LeetCode之每日一题》:223.第 N 位数字

第 N 位数字


题目链接: 第 N 位数字

有关题目

给你一个整数 n ,请你在无限的整数序列 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ...] 
中找出并返回第 n 位上的数字。
示例 1:

输入:n = 3
输出:3
示例 2:

输入:n = 11
输出:0
解释:第 11 位数字在序列 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... 里是 0 ,它是 10 的一部分。
提示:

1 <= n <= 2^31 - 1
第 n 位上的数字是按计数单位(digit)从前往后数的第 n 个数,参见 示例 2

题解

法一:直接计算
参考官方题解
Tips

下列代码中int digit = (num / (int)(pow(10, d - 1 - digitIndex))) % 10;
表示的意思为:
由于digitIndex是从左往右拿到num数字序列中的对应的数字。
上文代码采取从右往左拿到digitIndex的下一个下标,再num 除以pow(10, d - 1 - digitIndex)除掉所求数字 后面的所以数字。
最后模 10 拿到所求数字
class Solution {
public:
    int findNthDigit(int n) {
        //找到第n位上数字的位数d
        int d = 1, count = 9;
        while(n > (long)d * count)
        {
            n -= d * count;
            count *= 10;
            d++;
        }
        
        int index = n - 1;//在所有所有d位数构成的找到第n位数,注意下标从0开始
        int start = (int)pow(10, d - 1);//拿到最小的d位数所表示的数字
        int num = start + index / d;//获得第 n 个数字所处的数字
        int digitIndex = index % d;//获得第 n 个数字(num)所处的下标
        
        //获得第 n 个数字(num)所处的下标对应数字
        int digit = (num / (int)(pow(10, d - 1 - digitIndex))) % 10;
        return digit;
    }
};

在这里插入图片描述
法二:二分查找
参考官方题解

class Solution {
public:
    int findNthDigit(int n) {
        int low = 1, high = 9;
        while(low < high)
        {
            int mid = (high - low) / 2 + low;
            if (n > totalDigits(mid))
            {
                low = mid + 1;
            }
            else 
            {
                high = mid;
            }
        }
        
        int d = low;//拿到当前第 n 个数字所处位数
        //第 n 位数在所有 d 位数的序列中的下标,注意从下标从0开始
        int index = n - totalDigits(d - 1) - 1;
        int start = (int)pow(10, d - 1);
        int num = start + index / d;
        int digitIndex = index % d;
        int digit = (num / (int)(pow(10, d - 1 - digitIndex))) % 10;
        return digit;
    }

    int totalDigits(int length)
    {
        int digits = 0;
        int curLength = 1, curCount = 9;
        while(curLength <= length)  
        {
            digits += curLength * curCount;
            curLength++;
            curCount *= 10;
        }

        return digits;
    }
};

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值