# 统计数字

# 难度:中等

# 描述:

计算数字 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支持我一下~

最后更新时间: 8/2/2019, 12:38:18 PM