数字序列中某一位的数字

    科技2022-07-16  118

    找规律:

    0 占第0位 1~9 共9x1 = 9个数字 占位9x1 = 9 位 10~99 共9x10 = 90个数字 占位90x2 = 180 位 100~999 共9x100 = 900个数字 占位900x3 = 2700 位 …

    规律是不是很好理解啦,算法的逻辑就是:我们依次算一下占位数字,并不断地累加得到当前的总占位数,并判断和输入n的关系,总占位数小于n的话说明,第n位不在目前的范围內,继续累加;否则,说明在范围,然后找到相应数字返回。

    举个例子秒懂:

    假设输入n为14,我们想找到第14位:

    (1)此时设置当前位置为0的位置 temp=0 (2)占1位的数字有9个: num=9,(1~9,除了0因为temp已设为0了) (3)占1位 base=1 (4)我们判断一下,当占1位的数字都走完了,目前一共占到了多少位: temp + num x base = 0 + 9x1 = 9,说明占1位的数字走完后,当前占到了第9位。(更新temp=temp + num x base = 9) (5)和输入的值比较下,9 < 14,说明我们想找的第14位不在当前占1位的数字中。 (6)那就有可能在占2位的数字中,所以这一轮我们看看占2位的数字(10~99): 每个数字占位 base = base + 1 = 2 有多少个数字 num = num x 10 = 90 再回到第(4)步,算一下当占2位的数字也都走完了,目前一共占到了多少位 temp + num x base = 9 + 90 x 2 = 189 说明当占2位的数字走完后,当前占到了第189位 再回到第5步,发现 189 > 14,说明我们想找到的数字就在10~99之间 此时,循环终止…因为没必要再往下算占3位的情况了

    (7)我们知道第14位就在10~99之间的话就很好办了: 前一轮我们知道占1位的数字走完后,占到了第9位,那我们想找的第14位的值也就是9之后的第5位: 14 - 9 = 5位 占两位的数字中(10~99),第一个起始数字是10,(10 = 10的1次方,也就10的(base-1)次方) 由于10~99这个范围内的数字,都是占base=2位, 所以 5/2 = 2 10 + 2 = 12,第14位就在数字12里 5%2 = 1,说明第14位就是数字12中的第一个位置值,如果把12当成字符串,那就是下标为0的值 “12”.charAt(1-1) = 1 最终我们找到了这个1

    验证下0123456789101112…第14位确实是1

    联系上面的思路,带到下面的代码,很好理解啦。

    注意大数越界问题,所以这里用long型

    class Solution { public int findNthDigit(int n) { if(n<0) return 0; else if(n>=0 && n<=9) return n; else { long m = n; long temp = 0; long base = 1; long num = 9; char res = '0'; while((temp+base*num) < m) { temp += base*num; base += 1; num *= 10; } long a = (m-temp)/base; long b = (m-temp)%base; if(b!=0) { long c = (long) (Math.pow(10, base-1) + a); res = String.valueOf(c).charAt((int)b-1); }else { long c = (long) (Math.pow(10, base-1) + a - 1); res = String.valueOf(c).charAt((int)base-1); } return Integer.parseInt(String.valueOf(res)); } } }
    Processed: 0.009, SQL: 8