剑指offer——数字序列中某一位的数字

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

思路:

        如果一个一个数字去列举,然后统计数字的个数,这样来计算第n位对应的数字效率太慢了。所以要善于去发现一些规律,比如要找第1001位数字(题目里面说第五位是5,其实从0开始算的话,5应该是第六位数字,这一点为后面埋下了一点伏笔)。首先找出一位数的总数,0~9一共19个数字。10小于1001,那么抛开这10个数字,从后面的序列里面找第991位数字。两位数10~99的s数字个数为90个,包含90*2=180个单个数字,180小于991,那么抛开前面的数字,找从后面的序列开始第991-180=811个数字。三位数100~999的个数为900个,包含900*3=2700个单个数字,2700>811,说明要找的这个数字在一个三位数中,右因为811=270*3+1,所以是从100开始的第270个数,即数字370的中间的数字7(伏笔在这里,本来是多1,但是确实是数字7而不是3,考虑到了开始计算了0的原因)。

 

代码:

//countOfIntegers得到m位的数字总共有多少个,例如输入2,则返回两位数(10~99)的个数90
int countOfIntergers(int digits)
{
	if (digits == 1)
		return 10;

	int count = (int)pow(10, digits - 1);
	return 9 * count;
}

//求m位数的第一个数字,比如第一个两位数是10,第一个三位数是100,
int beginNumber(int digits)
{
	if (digits == 1)
		return 0;

	return (int)pow(10, digits - 1);
}

//如果知道要找的那一位数字位于某m位数字之后,就用下面的函数找出那一位数字
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 = countOfIntergers(digits);
		if (index < numbers*digits)//数字位数*数字个数
		{
			return digitAtIndex(index, digits);
		}

		index -= digits * numbers;
		digits++;
	}
	return -1;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值