
思路:模拟+双指针
- 由题意可知,一个数字既作为字符串分组元素,又作为分组计数,所以拟定两个指针i,j分别指向字符串元素和其对应的计数元素位置,同时记录答案;
- 易知指针j一定落后于i,所以记录i作为循环结束点;
- 按照规则依次构造字符串,填入1时结果res加一;
- 因为可能填入两个元素,所以会构造出过长的字符串,在每轮循环结束时进行判断。
Java
class Solution {
public int magicalString(int n) {
StringBuilder sb = new StringBuilder();
sb.append("01");
int res = 1;
for (int i = 1, j = 1; i < n; j++) {
int last = sb.charAt(sb.length() - 1) - '0';
int count = sb.charAt(j) - '0';
if (last == 1) {
if (count == 1) {
sb.append("2");
i++;
}
else {
sb.append("12");
res++;
i += 2;
}
}
else {
if (count == 1) {
sb.append("1");
res++;
i++;
}
else {
sb.append("21");
res++;
i += 2;
}
}
if (sb.length() > n + 1 && sb.charAt(sb.length() - 1) - '0' == 1)
return res - 1;
}
return res;
}
}
- 时间复杂度:O(n)
- 空间复杂度:O(n)
C++
class Solution {
public:
int magicalString(int n) {
string s = "";
s += "01";
int res = 1;
for (int i = 1, j = 1; i < n; j++) {
int last = s[s.size() - 1] - '0';
int count = s[j] - '0';
if (last == 1) {
if (count == 1) {
s += "2";
i++;
}
else {
s += "12";
res++;
i += 2;
}
}
else {
if (count == 1) {
s += "1";
res++;
i++;
}
else {
s += "21";
res++;
i += 2;
}
}
if (s.size() > n + 1 && s[s.size() - 1] - '0' == 1)
return res - 1;
}
return res;
}
};
- 时间复杂度:O(n)
- 空间复杂度:O(n)
总结
- 一道还算简单的题,但是循环结束条件还是捋了半天,有疑惑冷静手推一些示例就是最好的解答办法。
- 不想写就偷懒Rust的第二天……