【剑指Offer】个人学习笔记_44_数字序列中某一位的数字

刷题日期:下午8:00 2021年5月10日星期一

个人刷题记录,代码收集,来源皆为leetcode

经过多方讨论和请教,现在打算往Java方向发力

主要答题语言为Java

题目:

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

难度中等119

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

请写一个函数,求任意第n位对应的数字。

示例 1:

输入:n = 3
输出:3

示例 2:

输入:n = 11
输出:0

限制:

  • 0 <= n < 2^31
题目分析

和43题类似,都是涉及到位数,需要找规律的题,不过这个如果能通过举例子找到一定的公式来计算的话,就会简便很多。

也不能通过之前的乘除十来简化。

前十是本身,然后二位数有90个,三位数900个,四位数9000个……首要问题还是先判断出是多少位,然后进行计算。

肯定不能通过设置条件硬分,这样的话范围那么广肯定不行,因此还是得找到规律。

初始解答:

没什么思路,参考他人。

评论里也是一片抱怨,这种找规律的题感觉就是在考数学,而不是编程。

学习K神的分析:

class Solution {
    public int findNthDigit(int n) {
        int digit = 1; //位数,默认1
        long start = 1;  //该位数范围内的第一个数,10 100 1000等
        long count = 9; //所占的位数,即尾,如果大于说明要一层一层增大寻找范围
        while(n > count) {
            n -= count; //大于尾则继续取差 9 180 2700
            digit++;//同时说明位数要加一了
            start *= 10;//同理
            count = digit * start * 9; //同理尾也要扩大,9 99 999等
        }
        //这时已经确定是几位数了,而且已经把相应的尾减去了
        //初步得到是在那个数里
        long num = start + (n - 1) / digit;
        //先转化为字符串类型,然后利用方法取对应位的值
        //减一是因为从0数的,不减大一位,对位数取余就知道在这个数的第几个了
        //要记住Java方法基本都是先小写再大写
        return Long.toString(num).charAt((n - 1) % digit) - '0'; //精髓
    }
}

太强了,执行结果:通过

显示详情 添加备注

执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户

内存消耗:34.9 MB, 在所有 Java 提交中击败了99.27%的用户

学习他人:

比较恶心的题一般评论区里面人也不会多,这题的题解都没多少人写。

方法一:

Aurora 2020-05-11 Java 和K神的一模一样。

/* 数字范围    数量  位数    占多少位
    1-9        9      1       9
    10-99      90     2       180
    100-999    900    3       2700
    1000-9999  9000   4       36000  ...

    例如 2901 = 9 + 180 + 2700 + 12 即一定是4位数,第12位   n = 12;
    数据为 = 1000 + (12 - 1)/ 4  = 1000 + 2 = 1002
    定位1002中的位置 = (n - 1) %  4 = 3    s.charAt(3) = 2;
*/
class Solution {
    public int findNthDigit(int n) {
        int digit = 1;   // n所在数字的位数
        long start = 1;  // 数字范围开始的第一个数
        long count = 9;  // 占多少位
        while(n > count){
            n -= count;
            digit++;
            start *= 10;
            count = digit * start * 9;
        }
        long num = start + (n - 1) / digit;
        return Long.toString(num).charAt((n - 1) % digit) - '0';
    }
}

方法二:

黑筋 2021-04-06

编程的第一法则:如果您的代码以某种莫名方式跑起来了,请不要在尝试修改它了

class Solution {
    public int findNthDigit(int n) {
        if(n==Integer.MAX_VALUE) return 2;//面向测试用例编程
        int number = 0,p = 0;//number:第n位的实际数字,n为此数字的右数p位
        for(int i=10,j=1;i<Integer.MAX_VALUE;i*=10,j++){
            if(n/j>=i){//n=n+10+100+1000+......使得n=number*number的位数
                n+=i;
            }else{
                number = n/j;
                p = j-n%j-1;
                break;
            }

        }
        for(int k = 0;k<p;k++){
            number/=10;
        }
        return number%10;
    }
}

方法三:

K神: 解题思路:

  • 将 101112 \cdots101112⋯ 中的每一位称为 数位 ,记为 n ;
  • 将 10, 11, 12, \cdots10,11,12,⋯ 称为 数字 ,记为 num ;
  • 数字 1010 是一个两位数,称此数字的 位数 为 22 ,记为 digit ;
  • 每 digitdigit 位数的起始数字(即:1, 10, 100, \cdots1,10,100,⋯),记为 start。

作者:jyd
链接:https://leetcode-cn.com/problems/shu-zi-xu-lie-zhong-mou-yi-wei-de-shu-zi-lcof/solution/mian-shi-ti-44-shu-zi-xu-lie-zhong-mou-yi-wei-de-6/
来源:力扣(LeetCode)

class Solution {
    public int findNthDigit(int n) {
        int digit = 1;
        long start = 1;
        long count = 9;
        while (n > count) { // 1.
            n -= count;
            digit += 1;
            start *= 10;
            count = digit * start * 9;
        }
        long num = start + (n - 1) / digit; // 2.
        return Long.toString(num).charAt((n - 1) % digit) - '0'; // 3.
    }
}

总结

以上就是本题的内容和学习过程了,属于找规律的数学题,能记住大概的思路,到时候推敲就行。

欢迎讨论,共同进步。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值