目录
剑指 Offer 44. 数字序列中某一位的数字
题解:
代码:
数字以0123456789101112131415…的格式序列化到一个字符序列中。在这个序列中,第5位(从下标0开始计数)是5,第13位是1,第19位是4,等等。
请写一个函数,求任意第n位对应的数字。
示例 1:
输入:n = 3
输出:3
示例 2:输入:n = 11
输出:0
限制:
0 <= n < 2^31
题解:
- 首先,将n与10进行比较,判断n是否小于10。如果n小于10,说明n就是第n个数字,直接返回n。
- 如果n大于等于10,进入循环。初始化变量m为1,表示当前位数为个位数;start为1,表示个位数的第一个数字为1;count为9,表示个位数的数字数量为9。
- 进入循环,判断n是否大于count。如果n大于count,说明n所在的数字位数不是个位数,需要继续向上找。执行循环体内的代码。
- 在循环体内,将n减去count,使n更新为剩余的数量。然后,将m加1,表示当前位数增加了一位。将start乘以10,表示下一位数的第一个数字。计算新的count,即m位数的数字数量。
- 回到循环的开头,继续判断n是否大于count。如果n小于等于count,说明n所在的数字位数为m,退出循环。
- 创建一个StringBuilder对象,用于构建结果数字的字符串表示。创建一个变量temp,并初始化为0,用于存储n在数字字符串中的索引位置。
- 在条件判断中,判断n是否可以整除m。如果n可以整除m,说明n刚好位于所在数字的末尾。将start-1+n/m作为字符串添加到StringBuilder中。将temp更新为m-1。
- 如果n不能整除m,说明n不位于数字的末尾。将start+n/m作为字符串添加到StringBuilder中。将temp更新为n%m-1。
- 最后,通过返回sb.charAt(temp)-'0'的值,将索引temp处的字符转换为对应的整数值,并作为结果返回。
- 总体思路就是通过循环来寻找n所在的位数m,并确定n所在的数字和在数字中的索引位置。然后,通过StringBuilder构建结果数字的字符串表示,并将目标数字转换为整数值返回。
代码:
class Solution { public int findNthDigit(int n) { if(n<10){ return n; } int m = 1; // 当前位数 long start = 1; // m 位数的第一个数字 long count = 9; // 当前位数的数字数量 //找到n在几位数上 while(n>count){ n-=count; m++; start*=10; count=m*start*9; } StringBuilder sb=new StringBuilder(); int temp=0; if(n%m==0){ //找到n所在的数字 sb.append(start-1+n/m); //n在这个数字的第几位(字符串从0开始计算,所以-1) temp=m-1; }else{ //找到n所在的数字 sb.append(start+n/m); //n在这个数字的第几位(字符串从0开始计算,所以-1) temp=n%m-1; } // -'0' 会将该字符和字符 '0' 进行减法运算。这是因为在字符的ASCII值中,字符 '0' 的值是 48。通过减去 '0',我们可以将字符 '0' 转换为整数 0,将字符 '1' 转换为整数 1, return sb.charAt(temp)-'0'; } }
结果: