神奇字符串 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
这个题其实看懂了就不难,这个序列是固定的所以我们就可以利用这个特性可以将其解答出来,用到了异或因为它1和2来回变换所以我们用异或就不用判断了,
下面看下我在leetcode和本地写的两个版本吧
leetcode,直接将数组拉满就不用malloc了,如果为了将内存减小,也可以动态判断
int magicalString(int n){
int y=1,sum=0,a[100005];
a[0]=1,a[1]=2;
for(int i=1,x=1; i<n; x++,i++)
{
if(a[x]==1)
{
a[i]=a[i-1]^3;
}else{
a[i]=a[i-1]^3;
i++;
a[i]=a[i-1];
}
}
for(int j=0;j<n;j++)
{
if(a[j]==1)
{
sum++;
}
}
return sum;
}
本地
#include<stdio.h>
#include<string.h>
#define max 10005
#define flag 1000
int a[max];
void magicalString()
{
int y=1;
for(int i=1,x=1; i<flag; x++,i++)
{
if(a[x]==1)
{
a[i]=a[i-1]^3;
}else{
a[i]=a[i-1]^3;
i++;
a[i]=a[i-1];
}
}
}
int sum()
{
int x=0;
for(int i=0;i<flag;i++)
{
if(a[i]==1)
{
x++;
}
}
return x;
}
int main()
{
memset(a,0,sizeof(a));
a[0]=1,a[1]=2,a[2]=2,a[3]=1;
magicalString();
printf("%d",sum());
return 0;
}
满分截图