• 剑指 Offer 44. 数字序列中某一位的数字


    题目描述:

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

    求解

    为了方便我们先不考虑0,1是第一位数。
    我们先把每个数字单独考虑,如下:
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 … 99 100 101 102 … 999 …
    对于长度位1的数,它们的各个位上的数字处于[ 1 1 1, 1 ∗ 9 ∗ 1 0 0 1*9*10^0 19100]这个范围内,对于长度为2的数字上的每一位他们处于 1 ∗ 9 ∗ 1 0 0 + 1*9*10^0 + 19100+[ 1 1 1, 2 ∗ 9 ∗ 1 0 1 2*9*10^1 29101]这个范围内。以次类推,我们可以得到长度为k>1的数字上的每一位的处于 1 ∗ 9 ∗ 1 0 0 + 1 ∗ 9 ∗ 1 0 1 + . . . + 1 ∗ 9 ∗ 1 0 ( k − 2 ) + 1*9*10^0 + 1*9*10^1 +...+1*9*10^{(k-2)}+ 19100+19101+...+1910(k2)+ [ 1 1 1, k ∗ 9 ∗ 1 0 ( k − 1 ) k*9*10^{(k-1)} k910(k1)]。
    对于给定的n,先求它所处的数是几位数(len),我们可以不断的减去 1 ∗ 9 ∗ 1 0 0 1*9*10^0 19100 1 ∗ 9 ∗ 1 0 1 1*9*10^1 19101,直到 n < = 1 ∗ 9 ∗ 1 0 ( l e n − 1 ) n <= 1*9 *10 ^{(len - 1)} n<=1910(len1)。于是给出如下代码:

    int len = 1;
    while(len * 9 * Math.pow(10, len - 1) < n){
    	n -= len * 9 * Math.pow(10, len - 1);
    	len++;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    使用以上代码我们可以求得n所处的位的数的长度,注意此时n已经不是从1开始的第n位数,而是从 1 0 l e n − 1 10^{len-1} 10len1的1开始的第n位数。
    我们先确定在n在第几个(x)长度为len的数上,使用如下代码即可

    	int x = n % len == 0 ? n/len: n/len + 1;
    
    • 1

    知道在n在第x个长度为len的数上,也就知道了n所在的数的值(val),和n在第x个数上的哪个(t)位置上。

    	int val = Math.pow(10, len -1) + x - 1;
    	int t = n - len*(x - 1);
    
    • 1
    • 2

    求出val上的第t位即可(从高到低)。

    	int ret = (val%Math.pow(10, len - t + 1))/Math.pow(10, len - t);
    
    • 1

    下面是完整代码,对于n位0的情况同样适用

        public int findNthDigit(int n) {
        	//求n所在的数的长度
            int len = 1;
            while(len * 9 * Math.pow(10, len - 1) < n){
    	        n -= len * 9 * Math.pow(10, len - 1);
    	        len++;
            }
            //求n在长度位len的数的第几个数上,如果n%len = 0,说明它就在n/len这个数上,否则在后面一个数上。
            int x = n % len == 0 ? n/len: n/len + 1;
            //求第x个数的数值
            int val = (int)Math.pow(10, len -1) + x - 1;
            //求n在第x个数的哪个位上
    	    int t = n - len*(x - 1);
    	    //求val的第t位上的值
            int ret = (val%(int)Math.pow(10, len - t + 1))/(int)Math.pow(10, len - t);
            return ret;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
  • 相关阅读:
    关于城市旅游的HTML网页设计 HTML+CSS上海博物馆网站 dreamweaver作业静态HTML网页设计 html网页制作期末大作业
    哈夫曼编码(Huffman coding)
    【java核心技术】Java知识总结 -- 泛型程序设计一
    unigui点击按钮后弹出悬浮窗,几秒钟后关闭
    实用的嵌入式编码技巧:第三部分
    开发Qt上位机获取阿里云IOT设备数据(开发上位机对接阿里云IOT平台)
    游戏d3dcompiler_43.dll缺失怎么修复,分享5个快速有效的修复方法
    浅谈mysql扩展之读写分离、垂直分区、水平分区
    世界上第一个“半机械人”去世,改造自己只为“逆天改命”
    c语言tips-c语言的虚函数实现
  • 原文地址:https://blog.csdn.net/zyf7764029/article/details/126898298