leetcode 481. 神奇字符串 击败100%

神奇的字符串 S 只包含 ‘1’ 和 ‘2’,并遵守以下规则:

字符串 S 是神奇的,因为串联字符 ‘1’ 和 ‘2’ 的连续出现次数会生成字符串 S 本身。

字符串 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’ 的数目。

注意:N 不会超过 100,000。

示例:

输入:6 输出:3 解释:神奇字符串 S 的前 6 个元素是 “12211”,它包含三个 1,因此返回 3。

public int magicalString(int n) {
        if (n < 1) {
            return 0;
        } else if (n < 4) {
            return 1;
        } else if (n == 4) {
            return 2;
        } else if (n == 5) {
            return 3;
        }
        //神奇串本身12211212212211
        char[] A = new char[n];
        A[0] = '1';
        A[1] = '2';
        A[2] = '2';
        //神奇串1、2计数的串
        int slowPos = 2;
        //神奇串本身
        int fastPos = 3;
        int count = 1;
        //只循环到n-2,留最后一位,因为循环里面有可能fastPos会自增两次
        while (fastPos < n - 1) {
            //如果slowPos=='2',说明接下来fastPos要拼两次1或者2字符
            if (A[slowPos] == '2') {
                //拼两个2,但是1的计数count不会增加
                if (A[fastPos - 1] == '1') {
                    //这里是为什么循环只到n-2偏移位
                    A[fastPos++] = '2';
                    A[fastPos++] = '2';
                } else {
                    A[fastPos++] = '1';
                    A[fastPos++] = '1';
                    //1的计数连加两次
                    count += 2;
                }
            } else {
                //字符只加一次
                if (A[fastPos - 1] == '1') {
                    A[fastPos++] = '2';
                } else {
                    A[fastPos++] = '1';
                    count++;
                }
            }
            slowPos++;
        }
        //如果串最后一位确实没处理,而且前面的字符是2,那么这时候肯定是在后面添加'1',因此计数也要加1
        if (fastPos == n - 1 && A[fastPos - 1] == '2') {
            return count + 1;
        }
        return count;


    }

思路是在字符数组构造快慢指针,快指针可以通过慢指针往后构造字符串,同时对1的个数计数,时间复杂度O(N)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值