问题描述
问题分析
分析题目,这是字符串处理的简单模拟。需要注意的地方是:String,StringBuilder以及StringBuffer的区别。
- 运行速度快慢:StringBuilder > StringBuffer > String
这是因为String是字符串常量,每次追加字符串时,都需要创建新的对象,原来的对象需要JVM的垃圾回收机制来处理,增加了时间和内存消耗;而StringBuilder、StringBuffer是字符串变量,追加字符串时是在原有对象的内存的基础上扩展,没有创建和回收的过程,相较于String提高了性能。
- 线程是否安全:String(线程不安全)、StringBuilder(线程不安全)、StringBuffer(线程安全)
StringBuilder和StringBuffer的使用几乎完全相同,唯一的区别就是线程的安全性不同。正是由于StringBuffer保证线程安全(支持同步锁),所以性能要比StringBuilder稍差一些。
- 总结:
- String:适合操作少量的数据时使用
- StringBuffer:适用于单线程下在字符缓冲区进行大量操作的情况
- StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况
- 时间复杂度:O( n ),其中 n 表示s的长度。
- 空间复杂度:O( n )。
Java代码
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {//特殊情况
if (numRows == 1) {
return s;
}
//HashMap保存每一行的String
HashMap<Integer, StringBuilder> map = new HashMap<Integer, StringBuilder>();
//转向标志
boolean type = false; //false代表向下
int rows = 0;
//遍历扫描原String
for (int i = 0; i < s.length(); i++) {
char str = s.charAt(i);
if(map.containsKey(rows)){
//在每一行的尾端添加游标所指的字符
map.put(rows, map.get(rows).append(str));
}else {
map.put(rows, new StringBuilder(String.valueOf(str)));
}
//移动游标,转向
if (type){
//向上
rows -= 1;
if (rows == 0){
type = false;
}
}else {
//向下
rows += 1;
if (rows == numRows-1){
type = true;
}
}
}
//输出处理
StringBuilder result = new StringBuilder();
for (int i = 0; i < Math.min(numRows, s.length()); i++) {
result.append(map.get(i));
}
return result.toString();
}
}
结果分析
以上代码的执行结果:
执行时间 | 内存消耗 |
---|---|
53ms | 49.4MB |
我的思路和官方题解的思路是一样的,但是时间和内存的消耗差距不小,原因有待研究。以下是官方题解:
执行时间 | 内存消耗 |
---|---|
29ms | 45.1MB |
class Solution {
public String convert(String s, int numRows) {
if (numRows == 1) return s;
List<StringBuilder> rows = new ArrayList<>();
for (int i = 0; i < Math.min(numRows, s.length()); i++)
rows.add(new StringBuilder());
int curRow = 0;
boolean goingDown = false;
for (char c : s.toCharArray()) {
rows.get(curRow).append(c);
if (curRow == 0 || curRow == numRows - 1) goingDown = !goingDown;
curRow += goingDown ? 1 : -1;
}
StringBuilder ret = new StringBuilder();
for (StringBuilder row : rows) ret.append(row);
return ret.toString();
}
}