持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第30天,点击查看活动详情
第 30 天
神奇字符串
题目
神奇字符串 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
题解
解题思路 求前 n 个数字中 1 的数目 所以我们先自己构造一下长度为 n 的 s,然后统计 1 的个数
题目已经说了 122 开头
并且 1 组和 2 组交替出现,所以 122 的下一位已经由 22 决定了——不可能是 2,那就是 1,而 22 的第二个 2 又决定了 1 不止出现一次,所以就是 12211
...
也就是第 i 组放什么数字由最后一位决定——12 交替
第 i 组放多少个由下标为 i 的数字决定,1 或者 2
另外因为有可能一次性加两个,所以最后可能总长为 n+1 个,所以还要截取一下
小知识
12 之间转换可以通过
1^3 = 2, 2^3 = 1
/**
* @param {number} n
* @return {number}
*/
var magicalString = function (n) {
const s = [1, 2, 2];
for (let i = 2; s.length < n; i++) {
const last = s[s.length - 1];
for (let j = 0; j < s[i]; j++) {
s.push(last ^ 3);
}
}
return s.slice(0, n).filter(x => x === 1).length;
};