LeetCode 题解工作台
设计一个文本编辑器
请你设计一个带光标的文本编辑器,它可以实现以下功能: 添加: 在光标所在处添加文本。 删除: 在光标所在处删除文本(模拟键盘的删除键)。 移动: 将光标往左或者往右移动。 当删除文本时,只有光标左边的字符会被删除。光标会留在文本内,也就是说任意时候 0 都成立。 请你实现 TextEditor 类:…
6
题型
6
代码语言
3
相关题
当前训练重点
困难 · 链表指针操作
答案摘要
我们可以使用两个栈 和 ,其中栈 存储光标左边的字符,另一个栈 存储光标右边的字符。 - 当调用 方法时,我们将 中的字符依次入栈 。时间复杂度 。
Interview AiBoxInterview AiBox 实时 AI 助手,陪你讲清 链表指针操作 题型思路
题目描述
请你设计一个带光标的文本编辑器,它可以实现以下功能:
- 添加:在光标所在处添加文本。
- 删除:在光标所在处删除文本(模拟键盘的删除键)。
- 移动:将光标往左或者往右移动。
当删除文本时,只有光标左边的字符会被删除。光标会留在文本内,也就是说任意时候 0 <= cursor.position <= currentText.length 都成立。
请你实现 TextEditor 类:
TextEditor()用空文本初始化对象。void addText(string text)将text添加到光标所在位置。添加完后光标在text的右边。int deleteText(int k)删除光标左边k个字符。返回实际删除的字符数目。string cursorLeft(int k)将光标向左移动k次。返回移动后光标左边min(10, len)个字符,其中len是光标左边的字符数目。string cursorRight(int k)将光标向右移动k次。返回移动后光标左边min(10, len)个字符,其中len是光标左边的字符数目。
示例 1:
输入:
["TextEditor", "addText", "deleteText", "addText", "cursorRight", "cursorLeft", "deleteText", "cursorLeft", "cursorRight"]
[[], ["leetcode"], [4], ["practice"], [3], [8], [10], [2], [6]]
输出:
[null, null, 4, null, "etpractice", "leet", 4, "", "practi"]
解释:
TextEditor textEditor = new TextEditor(); // 当前 text 为 "|" 。('|' 字符表示光标)
textEditor.addText("leetcode"); // 当前文本为 "leetcode|" 。
textEditor.deleteText(4); // 返回 4
// 当前文本为 "leet|" 。
// 删除了 4 个字符。
textEditor.addText("practice"); // 当前文本为 "leetpractice|" 。
textEditor.cursorRight(3); // 返回 "etpractice"
// 当前文本为 "leetpractice|".
// 光标无法移动到文本以外,所以无法移动。
// "etpractice" 是光标左边的 10 个字符。
textEditor.cursorLeft(8); // 返回 "leet"
// 当前文本为 "leet|practice" 。
// "leet" 是光标左边的 min(10, 4) = 4 个字符。
textEditor.deleteText(10); // 返回 4
// 当前文本为 "|practice" 。
// 只有 4 个字符被删除了。
textEditor.cursorLeft(2); // 返回 ""
// 当前文本为 "|practice" 。
// 光标无法移动到文本以外,所以无法移动。
// "" 是光标左边的 min(10, 0) = 0 个字符。
textEditor.cursorRight(6); // 返回 "practi"
// 当前文本为 "practi|ce" 。
// "practi" 是光标左边的 min(10, 6) = 6 个字符。
提示:
1 <= text.length, k <= 40text只含有小写英文字母。- 调用
addText,deleteText,cursorLeft和cursorRight的 总 次数不超过2 * 104次。
进阶:你能设计并实现一个每次调用时间复杂度为 O(k) 的解决方案吗?
解题思路
方法一:左右栈
我们可以使用两个栈 和 ,其中栈 存储光标左边的字符,另一个栈 存储光标右边的字符。
- 当调用 方法时,我们将 中的字符依次入栈 。时间复杂度 。
- 当调用 方法时,我们将 中的字符出栈最多 次。时间复杂度 。
- 当调用 方法时,我们将 中的字符出栈最多 次,然后将出栈的字符依次入栈 ,最后返回 栈最多 个字符。时间复杂度 。
- 当调用 方法时,我们将 中的字符出栈最多 次,然后将出栈的字符依次入栈 ,最后返回 栈最多 个字符。时间复杂度 。
class TextEditor:
def __init__(self):
self.left = []
self.right = []
def addText(self, text: str) -> None:
self.left.extend(list(text))
def deleteText(self, k: int) -> int:
k = min(k, len(self.left))
for _ in range(k):
self.left.pop()
return k
def cursorLeft(self, k: int) -> str:
k = min(k, len(self.left))
for _ in range(k):
self.right.append(self.left.pop())
return ''.join(self.left[-10:])
def cursorRight(self, k: int) -> str:
k = min(k, len(self.right))
for _ in range(k):
self.left.append(self.right.pop())
return ''.join(self.left[-10:])
# Your TextEditor object will be instantiated and called as such:
# obj = TextEditor()
# obj.addText(text)
# param_2 = obj.deleteText(k)
# param_3 = obj.cursorLeft(k)
# param_4 = obj.cursorRight(k)
复杂度分析
| 指标 | 值 |
|---|---|
| 时间 | complexity depends on the operations and the final approach. In the worst case, adding or deleting text could involve traversing a portion of the list, making it O(n) for each operation. However, if the approach is optimized with direct node manipulation, many operations can be O(1). Space complexity is O(n) due to the storage required for the linked list nodes. |
| 空间 | Depends on the final approach |
面试官常问的追问
外企场景- question_mark
Focus on managing text and cursor efficiently with minimal overhead.
- question_mark
Test edge cases where the cursor is near the start or end of the text.
- question_mark
Evaluate the candidate’s ability to balance between time complexity and space usage in this linked-list-based approach.
常见陷阱
外企场景- error
Not handling edge cases where the cursor is at the beginning or end of the text.
- error
Inefficiently traversing the list during cursor movements or text modifications.
- error
Not maintaining the cursor’s position correctly when operations are interleaved.
进阶变体
外企场景- arrow_right_alt
Design a similar text editor but with undo/redo functionality.
- arrow_right_alt
Modify the design to support searching for a substring or replacing text.
- arrow_right_alt
Extend the design to support multi-cursor behavior and simultaneous edits.