题目要求
A magical string S consists of only '1' and '2' and obeys the following rules:
The string S is magical because concatenating the number of contiguous occurrences of characters '1' and '2' generates the string S itself.
The first few elements of string S is the following: S = "1221121221221121122……"
If we group the consecutive '1's and '2's in S, it will be:
1 22 11 2 1 22 1 22 11 2 11 22 ......
and the occurrences of '1's or '2's in each group are:
1 2 2 1 1 2 1 2 2 1 2 2 ......
You can see that the occurrence sequence above is the S itself.
Given an integer N as input, return the number of '1's in the first N number in the magical string S.
Note: N will not exceed 100,000.
Example 1:
Input: 6
Output: 3
Explanation: The first 6 elements of magical string S is "12211" and it contains three 1's, so return 3.
这题是描述了一个魔法字符串,该字符串完全由数字1和2构成。这个字符串的魔法点在于,如果将该该字符串连续的数字数量进行统计并且构成一个新的字符串,会发现新的字符串与原来的字符串完全相同。
比如1 22 11 2 1 22 1 22 11 2 11 22
字符串,经过统计后发现有1个1,2个2,2个1,1个2,1个1,2个2,1个1,2个2,2个1,1个2,2个1,2个2
,将统计的数量合并为新的字符串,会发现新的字符串为1 22 11 2 1 22 1 22
,和原字符串完全匹配。
思路和代码
用双指针可以快速的解决这个问题。假设让一个指针指向魔法字符串中统计位,将另一个指针指向魔法字符串中的数字位,则可以不断的通过统计位推理出当前的数字位值为多少。如果填入数字位的值为1,则把计数加一。代码如下:
public int magicalString(int n) {
if(n == 0) return 0;
if(n <= 3) return 1;
int a[] = new int[n+1];
a[0] = 1;
a[1] = 2;
a[2] = 2;
int leftPointer = 2, rightPointer = 3, num = 1, count = 1;
while(rightPointer < n) {
for(int i = 0 ; i < a[leftPointer] && rightPointer < n ; i++) {
a[rightPointer++] = num;
if(num == 1) {
count++;
}
}
leftPointer++;
num ^= 3;
}
return count;
}