*************
C++
topic:面试题 17.06. 2出现的次数 - 力扣(LeetCode)
*************
看题:

还稍微理解了一下:
输入 13
那么在13前面的数字:
1 2 3 4 5 6 7 8 9 10 11 12 13
出现2的数字有 2 和 12,
其中,2 出现了2次。
又想暴力美学了,aesthetic of violent。
第一想法,2 ^ 10 = 1024,非常的搞笑,没有任何的相关性。
有突然想到,汤家凤老师说过,一个非常高级的骂人的话就是 你们都线性相关。

0 ~ 9 出现 1 次2;
10 ~19 出现 1 次2;
20 ~ 29 出现 10 + 1 次2;
30 ~ 39 出现 1 次2;
40 ~49 出现 1 次2;
50 ~ 59 出现 1 次2;
等等,如果只有1个数字,判断给定的这个数字中有多少个2,会是怎么样呢?
首先对10位取余数 n%10 , if == 2, count
接着 n / 10
再循环
int countTwosInNumber(int num) {
int count = 0;
while (num != 0) {
if (num % 10 == 2) {
count++;
}
num = num / 10;
}
return count;
}
那么,对n前面的每一个数字进行计算,只需要加一个循环:
class Solution {
public:
int numberOf2sInRange(int n) {
int totalTwos = 0;
for (int i = 0; i <= n; i++) {
totalTwos += countTwosInNumber(i);
}
return totalTwos;
}
int countTwosInNumber(int num) {
int count = 0;
while (num != 0) {
if (num % 10 == 2) {
count++;
}
num = num / 10;
}
return count;
}
};
结果,不出意外的,超时,但是结果是可以运行的,这个代码是OK的。

屎上雕花,尿中浣溪沙。
睡了个午觉,有了新的感想,一直喜欢简约的事情,喜欢一切聪明的人和事情。
换个方法,直接把所有的数字列出来,转换成字符串,寻找等于2的字符,输出:
class Solution {
public:
int numberOf2sInRange(int n) {
int count = 0;
for(int i = 0; i <= n; i++) {
string s = to_string(i);
for(char c : s) {
if(c == '2') {
count++;
}
}
}
return count;
}
};
结果还是一样的,可以运行但是超时。

重新想个办法,需要写一个方法来计算从0到n(包括n)中数字2出现的次数。

输入是25,输出是9,解释是2,12,20,21,22,23,24,25,其中22出现了两次。
理解这个问题。要计算每一位上数字2出现的次数,然后把所有位上的次数加起来。
具体来说,假设有一个数,有d位,从个位开始,逐位计算2出现的次数。
比如说,对于十位数,计算十位上2出现的次数。
需要找出在每一位上,数字2出现的次数,然后加起来。
比如n=25,是两位数。
需要分别计算个位和十位上2出现的次数。
对于个位:
从0到25,个位上2出现的次数是:2,12,22,共3次。
对于十位:
从0到25,十位上2出现的次数是:20,21,22,23,24,25,共6次。
所以总共是3 + 6 = 9次,和示例一致。
所以,怎么找一个通用的方法,来计算每一位上的2出现的次数呢?

让我参考一下别人的思路,
设当前位是第k位(从右开始,个位是第0位),n的第k位数字是current, cur for short,高位数字是high,低位数字是low。
| i | high | k | low | 0 |
| n | 1 | cur | 1 | 3 |
那么:
看不懂,直接放弃,下周一再说吧,真有点难。
下面是抄的代码:
class Solution {
public:
int numberOf2sInRange(int n) {
int count = 0;
int factor = 1; // 当前位的权值,初始为个位
while (factor <= n) {
int high = n / (factor * 10); // 高位数字
int current = (n / factor) % 10; // 当前位数字
int low = n % factor; // 低位数字
if (current < 2) {
count += high * factor;
} else if (current == 2) {
count += high * factor + low + 1;
} else {
count += (high + 1) * factor;
}
factor *= 10; // 移动到下一位
}
return count;
}
};
跟数学沾边的东西,确实有点难。



被折叠的 条评论
为什么被折叠?



