数学 - 44.数字序列中某一位的数字

在这里插入图片描述

思路:
锁定范围,算出具体数值,计算偏移,获得值。
1.锁定范围,我们要确定当前的 n 是在1位数,2位数,还是3位数。
2.计算出这个n具体所对应的值,例如10 对应10,11对应的10.
3.计算出偏移,10对应的是10的第一位数字,11对应的是10 的第二位数字,所以我们要算出他是具体的第几位数字
4.返回。

举个例子1001。
序列的前10位是0~9,这些都是1位数字,1001 > 10,所以它并不在这些数字里面,所以我们要跳过这一序列,再从后面紧跟的序列中找到第991(1001 - 10 = 991)位的数字。

接下来180位数字是90个数字组成,分别是10~99,由于991 > 180,所以它也不在两位数的范围内,所以跳过,继续寻找881位(991 - 180 = 881)

接下来是2700 位数字,由900个数字组成,分别是100 ~999的三位数,881 < 2700,所以它就是三位数字其中的某一位数字。
881 /3 = 270;
881 %3 = 1;
所以这就意味着,他是三位数字的第270个数字,也就是100+270;实际数字就是370;而偏移为 1, 也就是说它指向第1个数字,也就是7.

     public int findNthDigit(int n) {
        if(n < 0) return -1;

        int digits = 1;
        while(true){
          long number = countOfInteger(digits);
          if(n < digits* number){
              return digitAtIndex(n,digits);
          }
          n -= digits*number;
          digits++;

      }

    }

    //获得m位的数字总共有多少个
    private int countOfInteger(int digits){
        //一位数字只有10个
        if(digits == 1){
            return 10;
        }
        //两位数字有90个,10-99
        //三位数字都900个 100-999
        int count = (int) Math.pow(10,digits-1);
        return  9*count;
    }

    //已知数字的位数时获取结果
    private int digitAtIndex(int index , int digits){
        if(digits == 1) return index;
        //获得具体的数值,从最初值 + 偏移值就等于 实际值
        long number = beginNumber(digits) + index/digits;
        //算出在具体的哪一位偏移,如果是0,是3位数字,那么就只能从后往前/10 ,/10 两次。
        //如果是1,从后向前/10 一次,
        long offset = digits - index % digits;
        for(long i = 1;i < offset ;i++){
            number/=10;
        }
        //最后要对最后一位进行获取,返回
         return (int)number%10;
    }

    //获取m位数字的最小值,例如2位数字的最小值为10,三位数字最小值为100
    private  long beginNumber(int digits){
        if(digits == 1)return 0;

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


原创文章 139 获赞 23 访问量 5917

猜你喜欢

转载自blog.csdn.net/weixin_44916741/article/details/104542590
今日推荐