剑指 Offer 44. 数字序列中某一位的数字

一、题目:

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

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

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

示例 2:
输入:n = 11
输出:0

限制:0 <= n < 2^31
注意:本题与主站 400 题:400. 第 N 位数字相同。

二、思路和代码:

1、最简单的办法:
从0开始一一枚举,求出它是几位数、累加他之前的数字的所有位数,直到累加数>=n,从这些数字中找出对应的那一位。


//to do 
//即使写出来也肯定会因为超时通过不了

2、找规律:
举个例子分析:第1001位是多少???
序列仅有个位数的数为0-9(10位):1001>10,1001不在其中,我们只需要找后面第1001-10=991位即可;
序列接下来仅有两位数的数为10-99(180位):911>180,1001不在其中,我们只需要找后面第991-180=811位即可;
序列接下来仅有两位数的数为100-999(2700位):811<2700,1001在其中!
我们来找2700中第811位是什么,811/3(位数)=270且余数为1,
(需要注意的数每位都是从0开始的而不是1,0、10、100、1000…),所以刚刚100没算进去,所以,第1001位占满了100+269位,还剩余2位(一个是因为0,一个是因为余数),所以这个数应该是370的第二位,7!
计算方法:100+270=370,811就是370的第3-811%3=2位,=7。
我要休息一下!


class Solution {
public:
    int findNthDigit(int index) {//主函
        if(index < 0)return -1;//废物测试,边界处理,出于健壮性考虑,本题可有可无
	    int digits = 1;//dights表示 index是几位,默认一位
	    while(true){
            //digits位的数一共有number个
		    int numbers = countOfIntegers(digits); 
            //找到indexd 范围 ,1000000000会使得 numbers * digits 溢出int型
		    if(index < (long long) numbers * digits)return digitAtIndex(index, digits);
    		index -= digits * numbers;
    		digits++;
	    }
	    return -1;
    }
//digits位的数一共有几个
int countOfIntegers(int digits){
	return digits == 1?10:9 *pow(10, digits - 1);
}
//找出那个数字num,
int digitAtIndex(int index, int digits){
	int num = beginNumber(digits) + index / digits;
	int indexFromRight = digits - index % digits;//找到所求的在第几位
	for(int i = 1; i < indexFromRight; ++i)	num /= 10;
	return num % 10;
}
//digits位数的第一个数字
int beginNumber(int digits)
{
	return digits == 1?0:pow(10, digits - 1);
}
};

参考剑指offer书中思想,代码:何海涛->剑指offer,
但是,大神在书里面似乎是算错了,想让他退钱!剑指offer第二版P225:

在这里插入图片描述

怕什么真理无穷,进一步有进一步的欢喜!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

甜橙の学习笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值