这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战
1~n整数中1出现的次数
剑指Offer 43.1~n整数中1出现的次数
难度:困难
输入一个整数n,求1~n这n个整数的十进制表示中1出现的个数。
例如,输入12,1~12这些整数中包含1的数字有1、10、11和12,1一共出现了5次。
示例1:
输入:n = 12
输出:5
示例2:
输入:n = 13
输出:6
限制:1 <= n < 2^31
题解
归纳法
这道题纯用归纳解决
从个数到最高位遍历,将n看成「high、cur、low」这三个部分,其中cur为当前位数,high为cur之前的值,low为cur之后的值,根据当前位数,设digit为1、10、100......通过数学归纳法推理出:
- 当
cur = 0
,执行res += high * digit
- 当
cur = 1
,执行res += high * digit + low + 1
- 当
cur > 1
,执行res += high * digit + digit
/**
* @param {number} n
* @return {number}
*/
var countDigitOne = function (n) {
let digit = 1,
res = 0;
let high = Math.floor(n / 10),
cur = n % 10,
low = 0;
while (high !== 0 || cur !== 0) {
if (cur === 0) res += high * digit;
else if (cur === 1) res += high * digit + low + 1;
else res += high * digit + digit;
low += cur * digit;
cur = high % 10;
high = Math.floor(high / 10);
digit *= 10;
}
return res;
};
- 时间复杂度:O()
- 空间复杂度:O()
数字序列中某一位的数字
剑指Offer 44.数字序列中某一位的数字
难度:中等
数字以0123456789101112131415...的格式序列化到一个字符序列中。在这个序列中,第5位(从下标0开始计数)是5,第13位是1,第19位是4,等等。
请写一个函数,求任意第n位对应的数字。
示例1:
输入:n = 3
输出:3
示例2:
输入:n = 11
输出:0
限制:0 <= n < 2^31
题解
找规律
将101112...中的每一位称为数位n,将10,11,12...称为数字num,每digit位数的起始数字(1,10,100...)称为start。
数字氛围 | 位数digit | 数字数量 | 数位数量 |
---|---|---|---|
1~9 | 1 | 9 | 9 |
10~99 | 2 | 90 | 180 |
100~999 | 3 | 900 | 2700 |
... | ... | ... | ... |
start~end | digit | 9 * start | 9 * start * digit |
由表格得出:
- digit = digit + 1
- start = start * 10
- count = 9 * start * digit
求解思路:
- 确定n所在数字的位数,即digit
- 确定n所在的数字,即num
- 确定n是num中的哪一数位,并返回结果
- 确定n所在位数:
数字氛围 | 位数 | 数位数量 | n = n - count |
---|---|---|---|
1~9 | 1 | 9 | n - 9 |
10~99 | 2 | 180 | n - 9 -180 |
100~999 | 3 | 2700 | n - 9 - 180 -2700 |
start~end | digit | 9 * start * digit | 直至n <= count |
由表格得出:
- 所求位数在某个digit位数中
- 所求位数为从数字start开始的第n个位数
- 确定n所在的数字
digit = 2,start = 10
1 | 0 | 1 | 1 | 1 | 2 | ... | |
---|---|---|---|---|---|---|---|
n | 1 | 2 | 3 | 4 | 5 | 6 | ... |
(n - 1) | 0 | 1 | 2 | 3 | 4 | 5 | ... |
(n - 1) / 2 | 0 | 0 | 1 | 1 | 2 | 2 | ... |
由表格得出:
- 数字num = start + (n - 1) / digit
- 确定n是num中的哪一数位
1 | 0 | 1 | 1 | 1 | 2 | ... | |
---|---|---|---|---|---|---|---|
n | 1 | 2 | 3 | 4 | 5 | 6 | ... |
(n - 1) | 0 | 1 | 2 | 3 | 4 | 5 | ... |
(n - 1) % 2 | 0 | 1 | 0 | 1 | 0 | 1 | ... |
由表格得出:
- 所求数位在num的第(n - 1) % 2位
整体实现代码如下:
/**
* @param {number} n
* @return {number}
*/
var findNthDigit = function (n) {
let digit = 1,
start = 1,
count = 9;
while (n > count) {
n -= count;
digit += 1;
start *= 10;
count = digit * start * 9;
}
let num = Math.floor(start + (n - 1) / digit);
return Number(num.toString(10)[(n - 1) % digit])
};
坚持每日一练!前端小萌新一枚,希望能点个赞
哇~