简单说下遇到的问题,代码就不细说了(在最后),遇到只有超出时间限制的问题,然后看那案例真的无语,但再怎么计算我代码的时间复杂度,大概也就是O(n),就这怎么就超出时间复杂度呢?
直到我把String换成StringBuilder类型,直接就通过了,甚至还超过百分之八十多的人。问题就出在String了,接着我了解了两个方式的区别。
在Java中,字符串的拼接可以通过多种方式实现,但其中最常见的是使用字符串连接操作符 +
或者使用 StringBuilder类。
String的'+'连接:
这种方式会创建新的字符串对象,每个连接操作都会生成一个新的字符串对象。因此,如果有多个连接操作,可能会导致多次创建新的字符串对象,从而引起性能问题。其时间复杂度为 O(n^2),其中 n 是连接操作的次数。
StringBuilder:
使用 StringBuilder
的 append
方法会在同一个可变的字符串缓冲区上执行连接操作,避免了多次创建新的字符串对象。这种方式的时间复杂度为 O(n),其中 n 是连接操作的次数。
到这总算明白了报错的原因,string的+连接每次都会新建一个字符串,每次相当于平均O(n)复杂度,再加上拼接的n次,复杂度可不是O(n)吗,再结合那个离谱的案例,不超时间才怪呢,看来一些基础掌握的还是不牢。
题目代码:
class Solution {
public String repeatLimitedString(String s, int repeatLimit) {
int[] nums = new int[26];
for (int i = 0; i < s.length(); i++) {
nums[s.charAt(i) - 'a']++;
}
StringBuilder result = new StringBuilder();
int back = 0, flag = 25, flag2 = -1, back2 = 0;
for (int i = 25; i >= 0;) {
if (nums[i] == 0) {
i--;
continue;
}
if (back == 1 && nums[i] > 0) {
result.append((char)('a' + i));
nums[i]--;
flag2 = i;
back2 = 1;
i = flag;
back = 0;
continue;
}
if (nums[i] <= repeatLimit) {
for (int j = 0; j < nums[i]; j++) {
result.append((char)('a' + i));
}
if (back2 == 1 && flag2 != -1) {
i = flag2 + 1;
back2 = 0;
}
nums[i] = 0;
} else {
for (int j = 0; j < repeatLimit; j++) {
result.append((char)('a' + i));
}
nums[i] -= repeatLimit;
if (nums[i] > 0) {
back = 1;
flag = i;
}
if (back2 == 1 && flag2 != -1) {
i = flag2 + 1;
back2 = 0;
}
}
i--;
}
return result.toString();
}
}