44_剑指offer_java_数字序列中某一位的数字

本文探讨了如何求解数字序列中任意位置的数字,通过分析数字序列的特点,提出了一种高效算法。文章详细介绍了算法的实现过程,包括确定目标数字的位数、所属数及具体位置,并附带代码实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

题目描述

测试用例

题目考点

解题思路

自己解题


题目描述

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

 

测试用例

  • 功能测试(输入10、190、1000等)
  • 边界值测试(输入0、1等)

 

题目考点

  • 考察应聘者优化的激情和能力。最原始的方法大部分应聘者都能想到。当面试官提示还有更快的方法之后,应聘者千万不要轻易放弃尝试。必要的时候可以要求面试官给出提示。
  • 考察应聘者面对复杂问题的分析能力,可以通过分析具体例子一步步找到通用的规律。

 

解题思路

以第1001位数字7为例 步骤1:首先确定该数字是属于几位数的; 如果是一位数,n<9;如果是两位数,n<9+902=189;如果是三位数,n<189+9003=2889; 说明是三位数。(这里有个循环) 步骤2:确定该数字属于哪个数。100+(1001-190)/3= 370。 步骤3:确定是该数中哪一位。1001-190-(370-100)*3 = 1,所以位于“370”的下标为1的位置,即数字7

 

自己解题

package Sword;

public class Serialization {
	public static void main(String[] args) {
		Serialization serialization = new Serialization();
		System.out.println(serialization.digitAtIndex(19));
	}
	
	// ----求数字序列中某一位的数字--------------------
	public int digitAtIndex(int index) {
		if (index < 0) {
			return -1;
		}
		
		int digits = 1;
		while (true) {
			int numbers = countOfIntegers(digits); //功能函数: m位数字的总数
			if (index < numbers * digits) {
				// 在m位数的大范围内,
				return digitAtIndex(index, digits);// 功能函数,在m位数大范围中精确找到这个数字
			}
			// 更新下标和位数
			index -= numbers * digits;
			digits++;
		}
	}
	
	// ----知道要找的那位数字位于某m(digits)位数中后,使用下面的函数精准找出该数--------
	public int digitAtIndex(int index, int digits) {
		// 如 100 + 811/3, 即 起始 + 下标整除m,
		int number = beginNumber(digits) + index / digits;
		
		// 通用方法:取number中的从左到右第x位,就是从右到左的第 digits-x 位
		int indexFromRight = digits - index % digits;
		for (int i = 1; i < indexFromRight; ++i) {
			// 结果就是取number中的第 index % digits 位数,比如 811 % 3 = 1 ,取370的第1位数,注意是从第0位开始
			number /= 10;
		}
		return number % 10;
	}
	
	// -----求出m位数字的个数--------------------
	public int countOfIntegers(int digits) {
		if (digits == 1) {
			return 10;
		}
		int count = (int) Math.pow(10, digits - 1);
		return 9 * count;
	}
	
	// -----求m位数的第一个数字-------------------
	public int beginNumber(int digits) {
		if (digits == 1) {
			return 0;
		}
		return (int) Math.pow(10, digits - 1);
	}
	
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值