开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情
恐怖周一,要马上开启周会 + 需求了
神奇字符串
该题出自力扣的481题 —— 神奇字符串【中等题】
审题
神奇字符串 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 的数目。
- 这道题初看真的好拗口,而且对比了题意和测试用例,也不是很好理解。简单概括就是,整个字符串只有12,两种字符,而且字符之间必定交互出现,决定出现的数字个数与前一个数相关
- 数字出现的频率与前一个数相关,但是决定用哪个数字就是当前数字的前一个的逆反,例如:1则是2,2则是1
- 因此思路出来了,利用前三个数字去推导,也就是模拟题型
- 判断如果长度小于4,则直接剪枝
- 开辟一个char型数组,长度 n + 10,防止溢出
- 利用循环,不断推导
- 只要知道需要填充的数字
- 知道需要填充的个数
- 还原数组即可
- 最终返回即可
编码
class Solution {
public int magicalString(int n) {
if (n<4)return 1;
int sum = 1;
int[] chars = new int[n + 10];
chars[0] = 1;
chars[1] = 2;
chars[2] = 2;
int i = 3;
int q = chars[2];
for (int j = 2; j < n && i<n;j++) {
// 个数
int aChar = chars[j];
// 填充的数
q = (q ^ 3);
for (int k = 0; k < aChar && i + k<=n; k++) {
chars[i++] = q;
if (q == 1)sum++;
}
}
return sum;
}
}