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

描述

剑指offer JZ44 数字序列中某一位的数字
数字以 0123456789101112131415… 的格式作为一个字符序列,在这个序列中第 2 位(从下标 0 开始计算)是 2 ,第 10 位是 1 ,第 13 位是 1 ,以此类题,请你输出第 n 位对应的数字。

方法一:通过减去位数计算

思路:由于数字之间的差异点是在位数,所以我们可以把位数不同的数字分组,计算出这个位数所有数字的位数个数,然后计算n对应的位数区间,知道了n在哪个位数区间就可以定位到具体数字。
实现技巧 :1-9,一位数总共9个,10-99,两位数一共90个,100-999,三位数一共900个。可以发现,同一位数的个数=这个位数的起始数字9,比如二位数的个数 =109=90。得到数字的个数之后,再将个数乘以位数,即可得到这个位数的所有位数之和,比如两位数位数和就等于90*2=180;
代码实现与相应解释说明:

import java.util.*;
public class Solution {
    public int findNthDigit (int n) {
        //记录当前位数
        int digit = 1;
        //记录当前位数区间的起始数字
        long start = 1;
        //记录当前区间总共有多少位数
        long sum = 9;
        //将n定位在某个位数的区间中
        //当n大于这个区间时,则减去这个区间的位数和,便于判断是否在下一区间,
       // 并且便于在区间中准确定位
        while (n > sum) {
            n -= sum;
            start *= 10;
            digit++;
            //该区间的总共位数
            sum = 9 * start * digit;
        }
        //定位n在哪个数字上
        //因为此处多算了一次start这个数字,所以要-1;
        String num = "" + (start - 1 + Math.ceil((double)n  / digit) );
        //定位n在数字的哪一位上
        //常规逻辑应当想到,用n对位数取余来确定n在一个数字的第几位,比如余数为1,就在第一位,
        //但是我们需要的是坐标,坐标是从0开始的,所以需要经过如下数学处理
        //余数为1,index为0,余数为2,index为1.......只需要将所得结果-1。余数为0是特殊情况,index为位数-1
        int index = (n % digit == 0? digit : n % digit) -1 ;
        return Integer.parseInt(num.charAt(index)+"");
    }
}

方法二:位数补零法

思路:将低位数数字的位数,全部补成高位数。比如n在两位数区间,则需要将一位数补位成00,01,02…;若n在三位数区间,则需要将一位数补位为000,001,002…,将两位数补位为010,011,012…;并且n需要加上相应补位的位数,便于判断。
代码实现与相应解释说明:
说明:代码中的Math.pow(10,digit) (digit为当前最高位数),代表在当前digit下的数字个数。比如digit为2, 代表两位数,Math.pow(10,2)=100,当前有100个数字。

public class Solution {
   public int findNthDigit (int n) {
     //记录位数
     int digit = 1;
     //关键点,为什么是n需要+1。因为在没有补位时,n的数字是没有把0计算在内的(比如3代表1,2,3,并不是0,1,2)。
     //但是在n加上Math.pow(10,digit)时,是会给0补位的。比如不加1,对3补位就代表数字0,01,02,03,0处少了一个0.+1就是为
     //了把这个0补上,便于之后的计算
     n += 1;
     //寻找n在哪个位数,并把低位补充
     while (digit * Math.pow(10, digit) < n) {
       n += Math.pow(10,  digit);
       digit++;
       }
       //因为还有0,所以要减去1
     String num = (n / (double)digit - 1)+ ""
      //定位n在数字的哪一位上
      //常规逻辑应当想到,用n对位数取余来确定n在一个数字的第几位,比如余数为1,就在第一位,
      //但是我们需要的是坐标,坐标是从0开始的,所以需要经过如下数学处理
      //余数为1,index为0,余数为2,index为1.......只需要将所得结果-1。余数为0是特殊情况,index为位数-1
     int index = (n % digit == 0 ? digit : n % digit) - 1;
     return Integer.parseInt(num.charAt(index)+"");
   }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值