【LeetCode】481. Magical String
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.
// 理解了題意之後,發現這樣的magical string是需要構造的,因此,首先根據它的性質把這樣的字串構造出來,再進行統計。這樣比較清晰直接
// 具體構造過程見程式碼
class Solution {
public:
int magicalString(int n) {
if (n == 0) return 0;
// 只有1和2,用vector表示比string方便。
//構造時一次性可能增加兩個元素,索性就把vector稍微開大點
vector<int> res(n + 5, 0);
// 先給定三個初值,再進行構造比較方便
//(原本想只給定一個初值就進行構造,但程式碼寫起來總覺得怪怪的,索性直接給三個吧)
res[0] = 1;
res[1] = 2;
res[2] = 2;
// 兩個指標,ir指向準備當前已構造好的末尾位置,ig指向的數字幫助我們進行構造,ig<=ir
int ir = 2, ig = 2;
while (ir < n) {
// 從magical string的性質發現,每次構造要麼能直接構造兩個重複的數,要麼只能構造一個
// 且新構造的數總是和前面的數不同
res[ir+1] = (res[ir] == 1) ? 2 : 1;
if (res[ig] == 2) {
res[ir+2] = res[ir+1];
ir += 2;
} else {
ir += 1;
}
++ig;
}
// 最後進行1個數的統計,這裡用了for_each和count_if,還有lambda表示式
// 最近正好在補充相關知識,拿出來練習一下
int cnt = 0;
//for_each(res.begin(), res.begin()+n, [&cnt](int x) {if (x == 1) ++cnt;});
cnt = count_if(res.begin(), res.begin()+n, [](int x) {return (x == 1);});
return cnt;
}
};