剑指Offer——面试题44:数字序列中某一位的数字

面试题44:数字序列中某一位的数字
题目:数字以0123456789101112131415…的格式序列化到一个字符序列中。在这个序列中,第5位(从0开始计数)是5,第13位是1,第19位是4,等等。请写一个函数求任意位对应的数字。

解决方法:

我们用一个具体的例子来分析如何解决这个问题。比如,序列的第1001位是什么? 序列的前10位是0~9这10个只有一位的数字。显然第1001位在这10个数字之后,因此这10个数字可以直接跳过。我们再从后面紧跟着的序列中找第991(991=1001-10)位的数字。接下来180位数字是90个10~99的两位数。由于991>180,所以第991位在所有的两位数之后。我们再跳过90个两位数,继续从后面找881(991-180)位。接下来的2700位是900个100~999的三位数。由于811<2700,所以第881位是某个三位数中的一位。由于811=270*3+1,这意味着第811位是从100开始的第270个数字即370的中间一位,也就是7。

#include<iostream>
#include<algorithm>
#include<set>
#include<vector>
#include<cstring>
#include<cmath>
using namespace std;
int countOfInteger(int digits){  // 计算m位的数字总共有多少个? 1位10个, 2位90个, 3位900个... 
	if(digits==1) return 10;
	int count=(int)pow(10, digits-1);
	return 9*count;
}
int beginNumber(int digits){  // m位的数的第一个数字。第一个1位数0,  第一个2位数10, 第一个3位数100
	if(digits==1) return 0;
	return (int)pow(10, digits-1);
}
int digitAtIndex(int index, int digits){
	int number=beginNumber(digits)+index/digits;
	int indexFromRight=digits-index%digits;
	for(int i=1;i<indexFromRight;i++){
		number/=10;
	}
	return number%10;
}
int digitAtIndex(int index){
	if(index<0) return -1;
	int digits=1;
	while(true){
		int numbers=countOfInteger(digits);
		if(index<numbers*digits) return digitAtIndex(index, digits);
		
		index-=numbers*digits;
		digits++;
	}
	return -1;
}
int main() {
	printf("%d\n",digitAtIndex(1001)); 
	return 0;
}
发布了47 篇原创文章 · 获赞 48 · 访问量 1458

猜你喜欢

转载自blog.csdn.net/qq_35340189/article/details/104445242