数字序列中某一位的数字

题目描述

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


        最直观的方法就是从0开始逐一枚举每个数字。每枚举一个数字,就求出该数字是几位数,并把该数字的位数和前面所有数字的位数累加。如果位数之和仍然小于或者等于输入n,则继续枚举下一个数字。当累加的数位大于n时,那么第n位数字一定在这个数字里,再找出对应的那一位。

        换种思路,我们可以跳过若干个数字,找数字见的规律来求对应的数字。以求序列中1001位为例:
        序列的前10位是0~9,所以第1001位一定在10之后,因此这10个数可以直接跳过。我们再从后面紧跟的序列中找到第991(991=1001-10)位的数字。
        接下来180位数字是10~99的两位数。由于991>180,所以第991位所有的两位数之后。我们再跳过90个两位数,继续从后面找881(881=991-180)位。
        接下来的2700位是900个100~999的三位数中的一位。由于881<2700,所以第881位是某个三位数中的一位。由于881=270+1,这意味着第881位是从100开始的第270个数字370的中间位,也就是7 。


于是可有以下代码:

package sword_offer;
// page 225 数组序列中的某一位数字
import java.lang.Math;
public class Solution44 {
    // 这里没采用原文中将程序拆分为几个小程序的形式,考虑到个位数的特殊性,直接在前面处理
    public static int digitAtIndex(int index) {
        if (index < 10) return index;
        int n = 2;    //位数
        index = index - 10;//初始化位位数为1的个数
        while(true) {
            int numsOfN = 9 * (int) Math.pow(10, n - 1);               //n位的个数
            if (index < numsOfN * n) {                                 //是否在这个区间
                int number = (int) Math.pow(10, n - 1) + index / n;    //对应的整数
                int indexFromRight = n - index % n;                    //从右边数第几位
                for (int i = 1; i < indexFromRight; i++) {             //找到那一位
                    number /= 10;
                }
                return number % 10;
            }
            index -= numsOfN * n;
            n++;
        }
    }
    
    // 测试
    public static void main(String[] args) {
        System.out.println(digitAtIndex(1001));
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值