比较暴力的解法,使用StringBuilder来模拟字符串的变化,完全数学化去理解,但性能会差一些,在题解区看到了有人提到了对顶栈。看了几篇介绍帖子,试着写了下,确实写起来更简单。
参考链接:对顶栈图解
class TextEditor {
/**
* 使用对顶栈解决字符移动问题:
* 一左一右两个栈left、right相对,添加时将字符串中字符都从队尾加入left栈
* 删除时,将left栈中的字符从队尾移除Math.min(left.size(), k)个字符
* 左移时,将需要移除的字符(数量为Math.min(left.size(), k))从left栈队尾取出并从队头放入right栈
* 右移时,将需要移除的字符(数量为Math.min(right.size(), k))从right栈队头取出并从队位放入left栈
*/
private LinkedList<Character> left = null;
private LinkedList<Character> right = null;
/**
* 初始化
*/
public TextEditor() {
left = new LinkedList<>();
right = new LinkedList<>();
}
/**
* 将 text中字符逐个从left栈队尾放入
* @param text 要入left栈的字符串
*/
public void addText(String text) {
for (Character c : text.toCharArray()){
left.addLast(c);
}
}
/**
* 删除光标左边 k 个字符。返回实际删除的字符数目。
* 将left栈中的字符从队尾移除Math.min(left.size(), k)个字符
* @param k 输入数字k
* @return 实际删除的字符数量
*/
public int deleteText(int k) {
int count = Math.min(left.size(), k);
for (int i = 0; i < count; i++) {
left.removeLast();
}
return count;
}
/**
* 将光标向左移动 k 次。返回移动后光标左边 min(10, len) 个字符,其中 len 是光标左边的 字符数目。
* 左移时,将需要移动的字符(数量为Math.min(left.size(), k))从left栈队尾取出并从队头放入right栈
* @param k 输入数字k
* @return 返回移动字符组成的字符串
*/
public String cursorLeft(int k) {
int count = Math.min(left.size(), k);
for (int i = 0; i < count; i++) {
Character character = left.removeLast();
right.addFirst(character);
}
return getLeftKCharacters(k);
}
/**
* 将光标向右边移动 k 次。返回移动后光标左边 min(10, len) 个字符,其中 len 是光标左边的 字符数目。
*
* @param k 输入数字k
* @return 返回移动字符组成的字符串
*/
public String cursorRight(int k) {
int count = Math.min(right.size(), k);
for (int i = 0; i < count; i++) {
Character character = right.removeFirst();
left.addLast(character);
}
return getLeftKCharacters(k);
}
/**
* 从队尾逐个获取left栈中的Math.min(left.size(),k)个字符
* @param k 输入数字k
* @return 返回取出字符组成的字符串
*/
public String getLeftKCharacters(int k) {
int len = Math.max(left.size() - 10,0);
StringBuilder str = new StringBuilder();
for (int i = len; i < left.size() ; i++) {
str.append(left.get(i));
}
return str.toString();
}
}