LeetCode-剑指44-数字序列中某一位的数字

在这里插入图片描述

1、找规律

我们通过找规律可以发现,当位数为 x x x时,其占用的位数为 x × 9 × 1 0 x − 1 x\times9\times10^{x-1} x×9×10x1。因此我们可以不断循环并增大位数 x x x直至 n − x < x × 9 × 1 0 x − 1 n-x<x\times9\times10^{x-1} nx<x×9×10x1,此时数字落在剩余的位数中。为了方便起见,我们去除0的情况即 i n d e x = n − 1 index = n - 1 index=n1。我们首先获得当前位数对应数字的起始值,即 s t a r t = ( i n t ) p o w ( 10 , d − 1 ) start = (int) pow(10, d - 1) start=(int)pow(10,d1)。而后我们计算我们对应的数字为 n u m = s t a r t + i n d e x / d num = start + index / d num=start+index/d。我们确定我们需要的数字在当前数字中的第 i n d e x % d index \% d index%d位。最终我们获得数字为 d i g i t = ( n u m / ( i n t ) ( p o w ( 10 , d − d i g i t I n d e x − 1 ) ) ) % 10 digit = (num / (int) (pow(10, d - digitIndex - 1))) \% 10 digit=(num/(int)(pow(10,ddigitIndex1)))%10

class Solution {
public:
    int findNthDigit(int n) {
        int d = 1, count = 9;
        while (n > (long) d * count) {
            n -= d * count;
            d++;
            count *= 10;      
        }
        int index = n - 1;
        int start = (int) pow(10, d - 1);
        int num = start + index / d;
        int digitIndex = index % d;
        int digit = (num / (int) (pow(10, d - digitIndex - 1))) % 10;
        return digit;
    }
};

2、二分查找

具体思路同上,区别在于我们可以通过范围确定位数不超过9,从而使用二分查找来直接进行查询。

class Solution {
public:
    int findNthDigit(int n) {
        int low = 1, high = 9;
        while (low < high) {
            int mid = (high - low) / 2 + low;
            if (totalDigits(mid) < n) {
                low = mid + 1;
            } else {
                high = mid;
            }
        }
        int d = low;
        int prevDigits = totalDigits(d - 1);
        int index = n - prevDigits - 1;
        int start = (int) pow(10, d - 1);
        int num = start + index / d;
        int digitIndex = index % d;
        int digit = (num / (int) (pow(10, d - digitIndex - 1))) % 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;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值