问题描述
小U最近开发了一个独特的AI模型,它有一个有趣的特点:当你给出一系列数字时,例如从1到N,AI会将这些数字视为一个没有空格或逗号的连续字符串。例如,当你给定N=11时,AI会展示的内容是“1234567891011”。小U对数字“11”非常感兴趣,她想知道在这个连续字符串中,子字符串“11”出现的次数是多少。
你需要帮助小U编写一个程序,给定一个整数N,计算子字符串“11”在AI模型感知的序列中出现的次数。
测试样例
样例1:
输入:
N = 11
输出:1
样例2:
输入:
N = 100
输出:2
样例3:
输入:
N = 111
输出:6
问题分析
模拟
这是一道中等难度的题目,我们需要从1~N所有拼接数字的字符串中,寻找到其中“11”子串出现的次数。例如,当N=11时,连续字符串是“1234567891011”,其中“11”出现了一次。
我们采用简单模拟的思路:先生成该字符串,再查询该字符串中出现了多少次“11”。
算法步骤
-
生成连续字符串
- 从1到N遍历每个数字,将其转换为字符串并拼接在一起。
- C++可以直接使用 to_string() 函数将一个数字转化为string类型,然后再将其拼接在总的字符串后方。
-
查找子字符串“11”
- 遍历生成的字符串,检查每个位置是否是“11”。
- 如果找到“11”,则增加计数器。
-
返回计数总数
代码实现
int solution(int N) {
string s;
for(int i=1;i<=N;i++) {
string t = to_string(i);
s += t;
}
int cnt = 0;
for(int i=1;i<s.size();i++) {
if(s[i-1] == '1' && s[i] == '1')
cnt ++;
}
return cnt;
}
小优化
我们其实可以对代码进行一些小优化,可以发现,如果一个数字内部并不含有字符1,那么这个字符串对结果一定是没有计数的,我们用一个*去代替原字符串,就可以省下很多的空间和时间。
而总串中连续的多个*也没有意义,所以我们对于连续一段不包含1的数字,都仅仅需要存储一个*即可。
int solution(int N) {
string s;
for(int i=1;i<=N;i++) {
string t = to_string(i);
if(t.find("1") == -1) {
if(s.back() == '1') s += '*';
continue;
}
s += t;
}
int cnt = 0;
for(int i=1;i<s.size();i++) {
if(s[i-1] == '1' && s[i] == '1')
cnt ++;
}
return cnt;
}
豆包小技巧
写完这一道题之后,我让豆包MarsCode AI给我总结了一下这道题目,他告诉了我一个不需要to_string的简单字符串拼接方法std::stringstream。
优化字符串拼接:考虑使用std::stringstream来拼接字符串,这样可以避免多次内存分配和复制。