剑指Offer(第二版)面试题44:数字序列中某一位的数字

剑指Offer(第二版)面试题18:删除链表的节点

题目:

数字按照0123456789101112131415161718192021…的顺序排列。第5位(从0开始计数)为5,第13位为1,第19位为4…… 求任意第n位对应的数字。

思路

  • 直观方法做枚举。每枚举一个数字的时候,求出该数字是几位数,并把数字的位数和前面的所有数字的位数相加。当累加的数位大于n时,那么第n位数字一定在这个数字里。
  • 当然正确的思路是找出某些规律跳过若干数字。例如:序列前十位是0~9。接下来180位数字是90个10~99的两位数。接下来的2700位是900个100~999的三位数。

代码

#include <iostream>
#include <cmath>

using namespace std;

int core(int num);
int getSizeOfDigit(int i);
int getResult(int digit,int num);

int main()
{
    int num = 0;
    while(num != -1)
    {
    cout << "type a size" << endl;
    cin >> num;
    int result = core(num);
    cout << result << endl;
    }

    return 0;
}

int core(int num)
{
    if(num < 0)
        return -1;

    int digit = 1;
    while(true)
    {
        int numbers = getSizeOfDigit(digit);
        if(num < numbers * digit)
            return getResult(digit,num);

        num -= digit * numbers;
        ++digit;
    }

}

int getSizeOfDigit(int i)
{
    if(i == 1)
        return 10;
    return 9*std::pow(10,i-1);
}

int getResult(int digit,int num)
{
    int beginNum = 0;
    if(digit == 1)
        beginNum = 0;
    else
        beginNum = (int) std::pow(10,digit - 1);

    int resultNum = beginNum + num/digit;
    int countFromRight = digit - num % digit;
    for(int i = 0; i < countFromRight - 1; ++i)
        resultNum /= 10;
    return resultNum%10;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值