数字序列中某一位的数字

找规律:

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));
	   }

    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-玫瑰少年-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值