leetcode-神奇字符串

91 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情

题目描述

神奇字符串 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

思路

题目中已经给出了神奇字符串挺长的一段开头"1221121221221121122"。因为只能包含1和2,所以其实给定了开头后,是可以无限续写下去的。
我们取开头的3个字符串"122",分成"1"、"22"这2个字符组,根据规则,下一个字符组必然是包含2个字符,由于当前最后1个字符是'2',所以下一个字符必然是'1',因为如果是'2'的话,那就跟前面的最后一组会连起来,改变最后一组字符的数量,就不符合神奇字符串的定义了。
所以,构建的规律后,按照分组往后添加,用一个指针i指向当前代表字符组数量的下标,然后根据当前最后1个字符是1还是2,进行取反,拼接上s[i]个next字符。
依次向下拼接,直到长度足够n(由于是按组进行向后添加的,可能会大于n),就可以统计前n位中1的数量了。

Java版本代码

class Solution {
    public int magicalString(int n) {
        if (n <= 3) {
            return 1;
        }
        StringBuilder magical = new StringBuilder("122");
        int i = 2;
        while (magical.length() < n) {
            char next = '1';
            if (magical.charAt(magical.length() - 1) == '1') {
                next = '2';
            }
            for (int j = 0; j < magical.charAt(i) - '0'; j++) {
                magical.append(next);
            }
            i++;
        }
        int ans = 0;
        for (int j = 0; j < n; j++) {
            if (magical.charAt(j) == '1') {
                ans++;
            }
        }
        return ans;
    }
}