(C++)剑指offer-拓展:数字序列中某一位的数字(数位问题)

(C++)剑指offer-拓展:数字序列中某一位的数字

分析数字规律可以发现,个位数有9个(不包括0),2位数有90个(10 - 99),3位数有900个(100 - 999),依次类推;因此处理步骤主要为三个过程:
1.定位第n个数字所在的数属于i位数的区域;
2.定位第n个数字所在对应i位数区域中的哪一个i位数;
3.定位第n个数字在那个i位数中的第几位。
通过上述规律筛出,问题整体的时间复杂度为O(logn)。具体代码如下:

class Solution {
public:
    int digitAtIndex(int n) {
        long long i = 1, s = 9, base = 1; //i位数:如23,i=2;s对应数量:如i=2的两位数有90个,10至99;base该位数的第一个数如两位数的第一个数是10
        while(n > i * s){ //opps
            n -= i * s;
            i++;
            s *= 10;
            base *= 10;
        }
        
        int num = base + (n + i - 1) / i - 1; //步骤2.求解对应i位数中的哪一个,(n + i - 1) / i表示 n / i向上取整,如8 / 3 = 3,最后减1是因为i = 1时,没包括0,但是序列是从0开始的因此左移一位消除
        int r = n % i ? n % i : i; //确定是步骤2.中数字的哪一位
        for(int j = 0; j < i - r; j++){ //如1243第3位,左移4 - 3 = 1位再取余即为所求
            num /= 10;
        }
        return num % 10;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值