剑指offer第二版——面试题44(java)

面试题:数字序列中某一位的数字

题目:

数字以0123456789101112131415……的格式序列化到一个字符序列中。

在这个序列中,第5位(从0开始计数)是5,第13位是1,第19位是4,等等

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

思路:

先定位到第n位是对应的一个几位数

再定位第n位是对应的这个x位数的哪个数字

再定位是这个数字的第几个位置的数字

1. 定位到第n位是对应的一个几位数

由数字规律可得,0~9有10个数,10~99有90个数,100~999有900个数……——只有0~9为特例,可单独处理,其他r位数,皆有9×pow(10,r-1)个数

因此,对应输入n,如果n<10,直接输出n;

如果n>10,说明指向的数至少为2位数,此时记位数为digit=2,此时的pow(10,digit-1)=loc=10

将1位数的数量减掉,用n-10,再比较n-10与90*2(也就是9*digit*loc)的大小,

两种情况:

如果还需要遍历的数字个数大于180个,说明是至少为3位数——减去2位数的数字个数,将loc=loc*10(因为3位数是以100计),digit=3(表示为三位数),继续减,直到x>9*digit*loc条件不成立,此时的digit为指向的数是几位数

如果小于180个,则说明需要定位的数为2位数

 

2. 定位第n位是对应的这个x位数的哪个数字

如果此时定位的结果是 digit=3,x=4,loc=100   

说明此时在100101102103……这个序列中,第n个数位于第4个位置(从0开始计数),由于是3位数,且序列的开始为loc(每个digit位数的数字开头都为loc),所以定位数字为current = loc + x/digit 

 

3. 定位是这个数字的第几个位置的数字

x%digit表示是数字中的第几位

(代码实现中因为直接用了转字符串方便读取指定位数的值,所以在return的时候-48转为了数字)

 

代码:

public class Q44 {
	public static void main(String[] args) {
		String numStr = "";
		for(int i=0;i<120;i++) {
			String temp = i + "";
			numStr = numStr + temp;
		}
		
		for(int i=0;i<200;i++) {
		System.out.printf("i:%d  %c——%d\n",i,numStr.charAt(i),findDigits(i));
		}
	}
	
	
	// 是指向第几位的数字
	public static int findDigits(int x) {
		if(x<10) {
			return x;
		}else {
			x = x-10;
		}
		
		int digit = 2;
		int loc = 10;
		while(x>9*digit*loc) {
			x = x-9*digit*loc;
			digit ++;
			loc *=loc;
		}
		
		// 定位第n位是对应的这个x位数的哪个数字
		int current = loc + x/digit;
		//System.out.printf("digit:%d,loc:%d,x:%d,current:%d\n", digit,loc,x,current);
		String re = current+"";
		
		//定位是这个数字的第几个位置的数字
		return re.charAt(x%digit)-48;
	}
}	

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值