Design a text editor with a cursor that can do the following:
When deleting text, only characters to the left of the cursor will be deleted. The cursor will also remain within the actual text and cannot be moved beyond it. More formally, we have that 0 <= cursor.position <= currentText.length always holds.
Implement the TextEditor class:
TextEditor() Initializes the object with empty text.void addText(string text) Appends text to where the cursor is. The cursor ends to the right of text.int deleteText(int k) Deletes k characters to the left of the cursor. Returns the number of characters actually deleted.string cursorLeft(int k) Moves the cursor to the left k times. Returns the last min(10, len) characters to the left of the cursor, where len is the number of characters to the left of the cursor.string cursorRight(int k) Moves the cursor to the right k times. Returns the last min(10, len) characters to the left of the cursor, where len is the number of characters to the left of the cursor.Example 1:
Input
["TextEditor", "addText", "deleteText", "addText", "cursorRight", "cursorLeft", "deleteText", "cursorLeft", "cursorRight"]
[[], ["leetcode"], [4], ["practice"], [3], [8], [10], [2], [6]]
Output
[null, null, 4, null, "etpractice", "leet", 4, "", "practi"]
Explanation
TextEditor textEditor = new TextEditor(); // The current text is "|". (The '|' character represents the cursor)
textEditor.addText("leetcode"); // The current text is "leetcode|".
textEditor.deleteText(4); // return 4
// The current text is "leet|".
// 4 characters were deleted.
textEditor.addText("practice"); // The current text is "leetpractice|".
textEditor.cursorRight(3); // return "etpractice"
// The current text is "leetpractice|".
// The cursor cannot be moved beyond the actual text and thus did not move.
// "etpractice" is the last 10 characters to the left of the cursor.
textEditor.cursorLeft(8); // return "leet"
// The current text is "leet|practice".
// "leet" is the last min(10, 4) = 4 characters to the left of the cursor.
textEditor.deleteText(10); // return 4
// The current text is "|practice".
// Only 4 characters were deleted.
textEditor.cursorLeft(2); // return ""
// The current text is "|practice".
// The cursor cannot be moved beyond the actual text and thus did not move.
// "" is the last min(10, 0) = 0 characters to the left of the cursor.
textEditor.cursorRight(6); // return "practi"
// The current text is "practi|ce".
// "practi" is the last min(10, 6) = 6 characters to the left of the cursor.
Constraints:
1 <= text.length, k <= 40text consists of lowercase English letters.2 * 104 calls in total will be made to addText, deleteText, cursorLeft and cursorRight.Follow-up: Could you find a solution with time complexity of O(k) per call?
In #2296 Design a Text Editor, you must simulate a text editor that supports inserting text, deleting characters, and moving the cursor left or right. The main challenge is performing these operations efficiently while maintaining the correct cursor position.
A common approach uses a doubly linked list to represent characters in the editor. The cursor can be treated as a pointer between nodes, allowing constant-time insertions and deletions near the cursor. When text is added, new nodes are inserted before the cursor. Deletions remove nodes to the left of the cursor, and cursor movement simply shifts the pointer across the list.
Another practical strategy is the two-stack technique, where characters to the left and right of the cursor are stored in separate stacks. Cursor movements transfer characters between stacks, while insert and delete operations modify the left stack. Both designs efficiently simulate editor behavior.
With these structures, most operations run in O(k) where k is the number of characters processed in that command, while maintaining efficient space usage.
| Approach | Time Complexity | Space Complexity |
|---|---|---|
| Doubly Linked List with Cursor | O(k) per operation (k = characters processed) | O(n) |
| Two-Stack Simulation | O(k) per operation | O(n) |
Sahil & Sarra
Use these hints if you're stuck. Try solving on your own first.
Making changes in the middle of some data structures is generally harder than changing the front/back of the same data structure.
Can you partition your data structure (text with cursor) into two parts, such that each part changes only near its ends?
Can you think of a data structure that supports efficient removals/additions to the front/back?
Try to solve the problem with two deques by maintaining the prefix and the suffix separately.
Watch expert explanations and walkthroughs
Practice problems asked by these companies to ace your technical interviews.
Explore More ProblemsJot down your thoughts, approach, and key learnings
Yes, design-based simulation problems like this frequently appear in FAANG-style interviews. They test a candidate’s understanding of data structures such as linked lists, stacks, and efficient state simulation.
A doubly linked list is well suited because it allows constant-time insertion and deletion around the cursor. Alternatively, two stacks can simulate the characters on the left and right of the cursor, making cursor movement and edits straightforward to implement.
The optimal approach typically uses a doubly linked list or a two-stack simulation. Both structures efficiently support cursor movement, insertion, and deletion near the cursor. They allow most editor operations to run in linear time relative to the number of characters processed.
A doubly linked list allows efficient traversal in both directions and constant-time updates around the cursor. This makes it ideal for simulating real editor operations such as inserting text, deleting characters, and moving the cursor left or right.