# 统计数字

# 难度:中等

# 描述:

计算数字 k 在 0 到 n 中的出现的次数,k 可能是 0~9 的一个值

# 样例:

n=12,k=1

在 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],我们发现 1 出现了 5 次 (1, 10, 11, 12)

返回 5

# 思路分析:

因为一个数可能会出现两次 k,转成字符串来操作,遍历字符来匹配 k。

如果可以的话,使用正则是更优解。

# 代码模板:

/**
 * @param k: An integer
 * @param n: An integer
 * @return: An integer denote the count of digit k in 1..n
 */
const digitCounts = function(k, n) {
	// write your code here
}
1
2
3
4
5
6
7
8

# 想一想再看答案

# 想一想再看答案

# 想一想再看答案

# 代码:

  1. 遍历 n 的范围,遍历数字
const digitCounts = function(k, n) {
	let count = 0
	k = k.toString()
	// 遍历n的范围
	for (let i = 0; i <= n; i++) {
		let str = i.toString() // 存字符
		for (let m = 0; m < str.length; m++) {
			//  遍历字符 计算出现两个k的情况
			if (str[m] === k) {
				count++
			}
		}
	}
	return count
}
console.log('输出:', digitCounts(1, 12)) // 5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  1. 将范围连接成一个字符串,遍历字符串
const digitCounts = function(k, n) {
	let sum = 0,
		s = [...Array(n + 1).keys()].join('') // 将数字范围转成数组再链接成字符串
	// 比如 s = "0123456789101112", n = 12
	k = k.toString() // 转字符用于判断
	for (var i = s.length - 1; i >= 0; i--) {
		// 遍历字符串 判断是否与k相等
		if (s[i] === k) {
			sum++
		}
	}
	return sum
}
console.log('输出:', digitCounts(1, 12)) // 5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  1. 最优:遍历范围,正则匹配
const digitCounts = function(k, n) {
	let num = 0
	let reg = new RegExp(`${k}`, 'g') // 正则 全局匹配k
	for (let i = 0; i <= n; i++) {
		let res = i.toString().match(reg) // 搜索i,返回一个匹配的数组
		if (res) {
			num = num + res.length // 匹配的数量
		}
	}
	return num
}
console.log('输出:', digitCounts(1, 12)) // 5
1
2
3
4
5
6
7
8
9
10
11
12

# 点个Star支持我一下~