一、题目
A magical string s consists of only '1' and '2' and obeys the following rules:
The string s is magical because concatenating the number of contiguous occurrences of characters '1' and '2' generates the string s itself.
The first few elements of s is s = "1221121221221121122……". If we group the consecutive 1's and 2's in s, it will be "1 22 11 2 1 22 1 22 11 2 11 22 ......" and the occurrences of 1's or 2's in each group are "1 2 2 1 1 2 1 2 2 1 2 2 ......". You can see that the occurrence sequence is s itself.
Given an integer n, return the number of 1's in the first n number in the magical string s.
来源:力扣
二、思路
首先题目给出神奇字符串 s 的定义:
仅由 1 和2 组成。
串联字符串中 1 和 2 的连续出现的次数可以生成该字符串。
并给出了字符串 s 的前几个元素:1221121221221121122 现在要求求出 s 的前 n个数字中 1 的数目,1 <= n >=10^5,那么我们可以按照定义来构造长度为 n的字符串 s,然后统计 s 中 1 的个数即可。那么如何通过现有的开头字符串来构造剩下的字符串呢——我们可以初始化字符串 s = 122,用指针 i 来指向现在需要构造的对应的组的大小,用指针 j来指向现在需要构造的对应组的位置,此时 i = 2,j=3。因为相邻组中的数字一定不会相同,所以我们可以通过 j 的前一个位置的数来判断当前需要填入的组中的数字。又因为每组的大小只为 1 或者 2,这保证了 j >i 在构造的过程中一定成立,即在指针j 处填入组时一定能确定此时需要填入的组的大小。这样我们就可以不断往下进行构造直到字符串长度到达 n。上述的过程中我们初始化字符串 s = 122,所以当 n < 4 时我们无需再往下构造,此时直接返回 1 即可.
三、代码
class Solution:
def magicalString(self, n: int) -> int:
if n < 4:
return 1
s = [''] * n
s[:3] = "122"
reslut = 1
i, j = 2, 3
while j < n:
size = int(s[i])
num = 3 - int(s[j - 1])
while size and j < n:
s[j] = str(num)
if num == 1:
reslut += 1
j += 1
size -= 1
i += 1
return reslut