神奇字符串
难度:
标签:
题目描述
神奇字符串 s
仅由 '1'
和 '2'
组成,并需要遵守下面的规则:
- 神奇字符串 s 的神奇之处在于,串联字符串中
'1'
和'2'
的连续出现次数可以生成该字符串。
s
的前几个元素是 s = "1221121221221121122……"
。如果将 s
中连续的若干 1
和 2
进行分组,可以得到 "1 22 11 2 1 22 1 22 11 2 11 22 ......"
。每组中 1
或者 2
的出现次数分别是 "1 2 2 1 1 2 1 2 2 1 2 2 ......"
。上面的出现次数正是 s
自身。
给你一个整数 n
,返回在神奇字符串 s
的前 n
个数字中 1
的数目。
示例 1:
输入:n = 6
输出:3
解释:神奇字符串 s 的前 6 个元素是 “122112
”,它包含三个 1,因此返回 3 。
示例 2:
输入:n = 1 输出:1
提示:
1 <= n <= 105
代码结果
运行时间: 55 ms, 内存: 20.2 MB
/*
思路:
虽然Java Stream不太适合处理这个问题,但我们可以先生成字符数组,然后使用Stream统计 '1' 的数量。
*/
import java.util.stream.IntStream;
public class MagicStringStream {
public int magicalString(int n) {
if (n == 0) return 0;
if (n <= 3) return 1;
int[] s = new int[n + 1];
s[0] = 1; s[1] = 2; s[2] = 2;
int head = 2, tail = 3, num = 1;
while (tail < n) {
for (int i = 0; i < s[head]; i++) {
s[tail] = num;
tail++;
}
num = num == 1 ? 2 : 1;
head++;
}
return (int) IntStream.range(0, n).filter(i -> s[i] == 1).count();
}
}
解释
方法:
此题解采用了模拟生成神奇字符串的过程。神奇字符串的生成规则是:利用当前字符串的字符来决定接下来添加的字符型号和数量。题解中,初始化神奇字符串为'1',从第一个字符开始,根据字符的值('1' 或 '2')来决定接下来添加的字符('2' 或 '1')。如果当前字符为'1',则添加一个'2';如果为'2',则添加两个'1'。同时,题解中使用了变量cur来表示当前处理的字符位置,num_sub表示已添加的字符数量。循环继续直到构建的字符串长度达到或超过n。最后,返回字符串中'1'的数量。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
在算法中,为什么在判断当前字符为'1'时,仅在某些情况下增加cur的值而不是每次都增加?
▷🦆
为什么在处理字符为'2'的情况下,需要检查字符串长度是否达到n两次,一次在添加第一个'1'后,另一次在可能的第二个'1'后?
▷🦆
在题解中,变量num_sub的作用是什么?是否与cur变量的作用重叠?
▷