mirror of
https://gitee.com/coder-xiaomo/leetcode-problemset
synced 2025-01-10 18:48:13 +08:00
203 lines
39 KiB
JSON
203 lines
39 KiB
JSON
{
|
||
"data": {
|
||
"question": {
|
||
"questionId": "2389",
|
||
"questionFrontendId": "2296",
|
||
"categoryTitle": "Algorithms",
|
||
"boundTopicId": 1531422,
|
||
"title": "Design a Text Editor",
|
||
"titleSlug": "design-a-text-editor",
|
||
"content": "<p>Design a text editor with a cursor that can do the following:</p>\n\n<ul>\n\t<li><strong>Add</strong> text to where the cursor is.</li>\n\t<li><strong>Delete</strong> text from where the cursor is (simulating the backspace key).</li>\n\t<li><strong>Move</strong> the cursor either left or right.</li>\n</ul>\n\n<p>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 <code>0 <= cursor.position <= currentText.length</code> always holds.</p>\n\n<p>Implement the <code>TextEditor</code> class:</p>\n\n<ul>\n\t<li><code>TextEditor()</code> Initializes the object with empty text.</li>\n\t<li><code>void addText(string text)</code> Appends <code>text</code> to where the cursor is. The cursor ends to the right of <code>text</code>.</li>\n\t<li><code>int deleteText(int k)</code> Deletes <code>k</code> characters to the left of the cursor. Returns the number of characters actually deleted.</li>\n\t<li><code>string cursorLeft(int k)</code> Moves the cursor to the left <code>k</code> times. Returns the last <code>min(10, len)</code> characters to the left of the cursor, where <code>len</code> is the number of characters to the left of the cursor.</li>\n\t<li><code>string cursorRight(int k)</code> Moves the cursor to the right <code>k</code> times. Returns the last <code>min(10, len)</code> characters to the left of the cursor, where <code>len</code> is the number of characters to the left of the cursor.</li>\n</ul>\n\n<p> </p>\n<p><strong class=\"example\">Example 1:</strong></p>\n\n<pre>\n<strong>Input</strong>\n["TextEditor", "addText", "deleteText", "addText", "cursorRight", "cursorLeft", "deleteText", "cursorLeft", "cursorRight"]\n[[], ["leetcode"], [4], ["practice"], [3], [8], [10], [2], [6]]\n<strong>Output</strong>\n[null, null, 4, null, "etpractice", "leet", 4, "", "practi"]\n\n<strong>Explanation</strong>\nTextEditor textEditor = new TextEditor(); // The current text is "|". (The '|' character represents the cursor)\ntextEditor.addText("leetcode"); // The current text is "leetcode|".\ntextEditor.deleteText(4); // return 4\n // The current text is "leet|". \n // 4 characters were deleted.\ntextEditor.addText("practice"); // The current text is "leetpractice|". \ntextEditor.cursorRight(3); // return "etpractice"\n // The current text is "leetpractice|". \n // The cursor cannot be moved beyond the actual text and thus did not move.\n // "etpractice" is the last 10 characters to the left of the cursor.\ntextEditor.cursorLeft(8); // return "leet"\n // The current text is "leet|practice".\n // "leet" is the last min(10, 4) = 4 characters to the left of the cursor.\ntextEditor.deleteText(10); // return 4\n // The current text is "|practice".\n // Only 4 characters were deleted.\ntextEditor.cursorLeft(2); // return ""\n // The current text is "|practice".\n // The cursor cannot be moved beyond the actual text and thus did not move. \n // "" is the last min(10, 0) = 0 characters to the left of the cursor.\ntextEditor.cursorRight(6); // return "practi"\n // The current text is "practi|ce".\n // "practi" is the last min(10, 6) = 6 characters to the left of the cursor.\n</pre>\n\n<p> </p>\n<p><strong>Constraints:</strong></p>\n\n<ul>\n\t<li><code>1 <= text.length, k <= 40</code></li>\n\t<li><code>text</code> consists of lowercase English letters.</li>\n\t<li>At most <code>2 * 10<sup>4</sup></code> calls <strong>in total</strong> will be made to <code>addText</code>, <code>deleteText</code>, <code>cursorLeft</code> and <code>cursorRight</code>.</li>\n</ul>\n\n<p> </p>\n<p><strong>Follow-up:</strong> Could you find a solution with time complexity of <code>O(k)</code> per call?</p>\n",
|
||
"translatedTitle": "设计一个文本编辑器",
|
||
"translatedContent": "<p>请你设计一个带光标的文本编辑器,它可以实现以下功能:</p>\n\n<ul>\n\t<li><strong>添加:</strong>在光标所在处添加文本。</li>\n\t<li><strong>删除:</strong>在光标所在处删除文本(模拟键盘的删除键)。</li>\n\t<li><strong>移动:</strong>将光标往左或者往右移动。</li>\n</ul>\n\n<p>当删除文本时,只有光标左边的字符会被删除。光标会留在文本内,也就是说任意时候 <code>0 <= cursor.position <= currentText.length</code> 都成立。</p>\n\n<p>请你实现 <code>TextEditor</code> 类:</p>\n\n<ul>\n\t<li><code>TextEditor()</code> 用空文本初始化对象。</li>\n\t<li><code>void addText(string text)</code> 将 <code>text</code> 添加到光标所在位置。添加完后光标在 <code>text</code> 的右边。</li>\n\t<li><code>int deleteText(int k)</code> 删除光标左边 <code>k</code> 个字符。返回实际删除的字符数目。</li>\n\t<li><code>string cursorLeft(int k)</code> 将光标向左移动 <code>k</code> 次。返回移动后光标左边 <code>min(10, len)</code> 个字符,其中 <code>len</code> 是光标左边的字符数目。</li>\n\t<li><code>string cursorRight(int k)</code> 将光标向右移动 <code>k</code> 次。返回移动后光标左边 <code>min(10, len)</code> 个字符,其中 <code>len</code> 是光标左边的字符数目。</li>\n</ul>\n\n<p> </p>\n\n<p><strong>示例 1:</strong></p>\n\n<pre>\n<strong>输入:</strong>\n[\"TextEditor\", \"addText\", \"deleteText\", \"addText\", \"cursorRight\", \"cursorLeft\", \"deleteText\", \"cursorLeft\", \"cursorRight\"]\n[[], [\"leetcode\"], [4], [\"practice\"], [3], [8], [10], [2], [6]]\n<strong>输出:</strong>\n[null, null, 4, null, \"etpractice\", \"leet\", 4, \"\", \"practi\"]\n\n<strong>解释:</strong>\nTextEditor textEditor = new TextEditor(); // 当前 text 为 \"|\" 。('|' 字符表示光标)\ntextEditor.addText(\"leetcode\"); // 当前文本为 \"leetcode|\" 。\ntextEditor.deleteText(4); // 返回 4\n // 当前文本为 \"leet|\" 。\n // 删除了 4 个字符。\ntextEditor.addText(\"practice\"); // 当前文本为 \"leetpractice|\" 。\ntextEditor.cursorRight(3); // 返回 \"etpractice\"\n // 当前文本为 \"leetpractice|\". \n // 光标无法移动到文本以外,所以无法移动。\n // \"etpractice\" 是光标左边的 10 个字符。\ntextEditor.cursorLeft(8); // 返回 \"leet\"\n // 当前文本为 \"leet|practice\" 。\n // \"leet\" 是光标左边的 min(10, 4) = 4 个字符。\ntextEditor.deleteText(10); // 返回 4\n // 当前文本为 \"|practice\" 。\n // 只有 4 个字符被删除了。\ntextEditor.cursorLeft(2); // 返回 \"\"\n // 当前文本为 \"|practice\" 。\n // 光标无法移动到文本以外,所以无法移动。\n // \"\" 是光标左边的 min(10, 0) = 0 个字符。\ntextEditor.cursorRight(6); // 返回 \"practi\"\n // 当前文本为 \"practi|ce\" 。\n // \"practi\" 是光标左边的 min(10, 6) = 6 个字符。\n</pre>\n\n<p> </p>\n\n<p><strong>提示:</strong></p>\n\n<ul>\n\t<li><code>1 <= text.length, k <= 40</code></li>\n\t<li><code>text</code> 只含有小写英文字母。</li>\n\t<li>调用 <code>addText</code> ,<code>deleteText</code> ,<code>cursorLeft</code> 和 <code>cursorRight</code> 的 <strong>总</strong> 次数不超过 <code>2 * 10<sup>4</sup></code> 次。</li>\n</ul>\n\n<p> </p>\n\n<p><strong>进阶:</strong>你能设计并实现一个每次调用时间复杂度为 <code>O(k)</code> 的解决方案吗?</p>\n",
|
||
"isPaidOnly": false,
|
||
"difficulty": "Hard",
|
||
"likes": 31,
|
||
"dislikes": 0,
|
||
"isLiked": null,
|
||
"similarQuestions": "[]",
|
||
"contributors": [],
|
||
"langToValidPlayground": "{\"cpp\": false, \"java\": false, \"python\": false, \"python3\": false, \"mysql\": false, \"mssql\": false, \"oraclesql\": false, \"c\": false, \"csharp\": false, \"javascript\": false, \"typescript\": false, \"bash\": false, \"php\": false, \"swift\": false, \"kotlin\": false, \"dart\": false, \"golang\": false, \"ruby\": false, \"scala\": false, \"html\": false, \"pythonml\": false, \"rust\": false, \"racket\": false, \"erlang\": false, \"elixir\": false, \"pythondata\": false, \"react\": false, \"vanillajs\": false, \"postgresql\": false}",
|
||
"topicTags": [
|
||
{
|
||
"name": "Stack",
|
||
"slug": "stack",
|
||
"translatedName": "栈",
|
||
"__typename": "TopicTagNode"
|
||
},
|
||
{
|
||
"name": "Design",
|
||
"slug": "design",
|
||
"translatedName": "设计",
|
||
"__typename": "TopicTagNode"
|
||
},
|
||
{
|
||
"name": "Linked List",
|
||
"slug": "linked-list",
|
||
"translatedName": "链表",
|
||
"__typename": "TopicTagNode"
|
||
},
|
||
{
|
||
"name": "String",
|
||
"slug": "string",
|
||
"translatedName": "字符串",
|
||
"__typename": "TopicTagNode"
|
||
},
|
||
{
|
||
"name": "Doubly-Linked List",
|
||
"slug": "doubly-linked-list",
|
||
"translatedName": "双向链表",
|
||
"__typename": "TopicTagNode"
|
||
},
|
||
{
|
||
"name": "Simulation",
|
||
"slug": "simulation",
|
||
"translatedName": "模拟",
|
||
"__typename": "TopicTagNode"
|
||
}
|
||
],
|
||
"companyTagStats": null,
|
||
"codeSnippets": [
|
||
{
|
||
"lang": "C++",
|
||
"langSlug": "cpp",
|
||
"code": "class TextEditor {\npublic:\n TextEditor() {\n\n }\n \n void addText(string text) {\n\n }\n \n int deleteText(int k) {\n\n }\n \n string cursorLeft(int k) {\n\n }\n \n string cursorRight(int k) {\n\n }\n};\n\n/**\n * Your TextEditor object will be instantiated and called as such:\n * TextEditor* obj = new TextEditor();\n * obj->addText(text);\n * int param_2 = obj->deleteText(k);\n * string param_3 = obj->cursorLeft(k);\n * string param_4 = obj->cursorRight(k);\n */",
|
||
"__typename": "CodeSnippetNode"
|
||
},
|
||
{
|
||
"lang": "Java",
|
||
"langSlug": "java",
|
||
"code": "class TextEditor {\n\n public TextEditor() {\n\n }\n \n public void addText(String text) {\n\n }\n \n public int deleteText(int k) {\n\n }\n \n public String cursorLeft(int k) {\n\n }\n \n public String cursorRight(int k) {\n\n }\n}\n\n/**\n * Your TextEditor object will be instantiated and called as such:\n * TextEditor obj = new TextEditor();\n * obj.addText(text);\n * int param_2 = obj.deleteText(k);\n * String param_3 = obj.cursorLeft(k);\n * String param_4 = obj.cursorRight(k);\n */",
|
||
"__typename": "CodeSnippetNode"
|
||
},
|
||
{
|
||
"lang": "Python",
|
||
"langSlug": "python",
|
||
"code": "class TextEditor(object):\n\n def __init__(self):\n\n\n def addText(self, text):\n \"\"\"\n :type text: str\n :rtype: None\n \"\"\"\n\n\n def deleteText(self, k):\n \"\"\"\n :type k: int\n :rtype: int\n \"\"\"\n\n\n def cursorLeft(self, k):\n \"\"\"\n :type k: int\n :rtype: str\n \"\"\"\n\n\n def cursorRight(self, k):\n \"\"\"\n :type k: int\n :rtype: str\n \"\"\"\n\n\n\n# Your TextEditor object will be instantiated and called as such:\n# obj = TextEditor()\n# obj.addText(text)\n# param_2 = obj.deleteText(k)\n# param_3 = obj.cursorLeft(k)\n# param_4 = obj.cursorRight(k)",
|
||
"__typename": "CodeSnippetNode"
|
||
},
|
||
{
|
||
"lang": "Python3",
|
||
"langSlug": "python3",
|
||
"code": "class TextEditor:\n\n def __init__(self):\n\n\n def addText(self, text: str) -> None:\n\n\n def deleteText(self, k: int) -> int:\n\n\n def cursorLeft(self, k: int) -> str:\n\n\n def cursorRight(self, k: int) -> str:\n\n\n\n# Your TextEditor object will be instantiated and called as such:\n# obj = TextEditor()\n# obj.addText(text)\n# param_2 = obj.deleteText(k)\n# param_3 = obj.cursorLeft(k)\n# param_4 = obj.cursorRight(k)",
|
||
"__typename": "CodeSnippetNode"
|
||
},
|
||
{
|
||
"lang": "C",
|
||
"langSlug": "c",
|
||
"code": "\n\n\ntypedef struct {\n \n} TextEditor;\n\n\nTextEditor* textEditorCreate() {\n \n}\n\nvoid textEditorAddText(TextEditor* obj, char* text) {\n \n}\n\nint textEditorDeleteText(TextEditor* obj, int k) {\n \n}\n\nchar* textEditorCursorLeft(TextEditor* obj, int k) {\n \n}\n\nchar* textEditorCursorRight(TextEditor* obj, int k) {\n \n}\n\nvoid textEditorFree(TextEditor* obj) {\n \n}\n\n/**\n * Your TextEditor struct will be instantiated and called as such:\n * TextEditor* obj = textEditorCreate();\n * textEditorAddText(obj, text);\n \n * int param_2 = textEditorDeleteText(obj, k);\n \n * char* param_3 = textEditorCursorLeft(obj, k);\n \n * char* param_4 = textEditorCursorRight(obj, k);\n \n * textEditorFree(obj);\n*/",
|
||
"__typename": "CodeSnippetNode"
|
||
},
|
||
{
|
||
"lang": "C#",
|
||
"langSlug": "csharp",
|
||
"code": "public class TextEditor {\n\n public TextEditor() {\n\n }\n \n public void AddText(string text) {\n\n }\n \n public int DeleteText(int k) {\n\n }\n \n public string CursorLeft(int k) {\n\n }\n \n public string CursorRight(int k) {\n\n }\n}\n\n/**\n * Your TextEditor object will be instantiated and called as such:\n * TextEditor obj = new TextEditor();\n * obj.AddText(text);\n * int param_2 = obj.DeleteText(k);\n * string param_3 = obj.CursorLeft(k);\n * string param_4 = obj.CursorRight(k);\n */",
|
||
"__typename": "CodeSnippetNode"
|
||
},
|
||
{
|
||
"lang": "JavaScript",
|
||
"langSlug": "javascript",
|
||
"code": "\nvar TextEditor = function() {\n\n};\n\n/** \n * @param {string} text\n * @return {void}\n */\nTextEditor.prototype.addText = function(text) {\n\n};\n\n/** \n * @param {number} k\n * @return {number}\n */\nTextEditor.prototype.deleteText = function(k) {\n\n};\n\n/** \n * @param {number} k\n * @return {string}\n */\nTextEditor.prototype.cursorLeft = function(k) {\n\n};\n\n/** \n * @param {number} k\n * @return {string}\n */\nTextEditor.prototype.cursorRight = function(k) {\n\n};\n\n/**\n * Your TextEditor object will be instantiated and called as such:\n * var obj = new TextEditor()\n * obj.addText(text)\n * var param_2 = obj.deleteText(k)\n * var param_3 = obj.cursorLeft(k)\n * var param_4 = obj.cursorRight(k)\n */",
|
||
"__typename": "CodeSnippetNode"
|
||
},
|
||
{
|
||
"lang": "TypeScript",
|
||
"langSlug": "typescript",
|
||
"code": "class TextEditor {\n constructor() {\n \n }\n\n addText(text: string): void {\n \n }\n\n deleteText(k: number): number {\n \n }\n\n cursorLeft(k: number): string {\n \n }\n\n cursorRight(k: number): string {\n \n }\n}\n\n/**\n * Your TextEditor object will be instantiated and called as such:\n * var obj = new TextEditor()\n * obj.addText(text)\n * var param_2 = obj.deleteText(k)\n * var param_3 = obj.cursorLeft(k)\n * var param_4 = obj.cursorRight(k)\n */",
|
||
"__typename": "CodeSnippetNode"
|
||
},
|
||
{
|
||
"lang": "PHP",
|
||
"langSlug": "php",
|
||
"code": "class TextEditor {\n /**\n */\n function __construct() {\n\n }\n\n /**\n * @param String $text\n * @return NULL\n */\n function addText($text) {\n\n }\n\n /**\n * @param Integer $k\n * @return Integer\n */\n function deleteText($k) {\n\n }\n\n /**\n * @param Integer $k\n * @return String\n */\n function cursorLeft($k) {\n\n }\n\n /**\n * @param Integer $k\n * @return String\n */\n function cursorRight($k) {\n\n }\n}\n\n/**\n * Your TextEditor object will be instantiated and called as such:\n * $obj = TextEditor();\n * $obj->addText($text);\n * $ret_2 = $obj->deleteText($k);\n * $ret_3 = $obj->cursorLeft($k);\n * $ret_4 = $obj->cursorRight($k);\n */",
|
||
"__typename": "CodeSnippetNode"
|
||
},
|
||
{
|
||
"lang": "Swift",
|
||
"langSlug": "swift",
|
||
"code": "\nclass TextEditor {\n\n init() {\n\n }\n \n func addText(_ text: String) {\n\n }\n \n func deleteText(_ k: Int) -> Int {\n\n }\n \n func cursorLeft(_ k: Int) -> String {\n\n }\n \n func cursorRight(_ k: Int) -> String {\n\n }\n}\n\n/**\n * Your TextEditor object will be instantiated and called as such:\n * let obj = TextEditor()\n * obj.addText(text)\n * let ret_2: Int = obj.deleteText(k)\n * let ret_3: String = obj.cursorLeft(k)\n * let ret_4: String = obj.cursorRight(k)\n */",
|
||
"__typename": "CodeSnippetNode"
|
||
},
|
||
{
|
||
"lang": "Kotlin",
|
||
"langSlug": "kotlin",
|
||
"code": "class TextEditor() {\n\n fun addText(text: String) {\n\n }\n\n fun deleteText(k: Int): Int {\n\n }\n\n fun cursorLeft(k: Int): String {\n\n }\n\n fun cursorRight(k: Int): String {\n\n }\n\n}\n\n/**\n * Your TextEditor object will be instantiated and called as such:\n * var obj = TextEditor()\n * obj.addText(text)\n * var param_2 = obj.deleteText(k)\n * var param_3 = obj.cursorLeft(k)\n * var param_4 = obj.cursorRight(k)\n */",
|
||
"__typename": "CodeSnippetNode"
|
||
},
|
||
{
|
||
"lang": "Dart",
|
||
"langSlug": "dart",
|
||
"code": "class TextEditor {\n\n TextEditor() {\n \n }\n \n void addText(String text) {\n \n }\n \n int deleteText(int k) {\n \n }\n \n String cursorLeft(int k) {\n \n }\n \n String cursorRight(int k) {\n \n }\n}\n\n/**\n * Your TextEditor object will be instantiated and called as such:\n * TextEditor obj = TextEditor();\n * obj.addText(text);\n * int param2 = obj.deleteText(k);\n * String param3 = obj.cursorLeft(k);\n * String param4 = obj.cursorRight(k);\n */",
|
||
"__typename": "CodeSnippetNode"
|
||
},
|
||
{
|
||
"lang": "Go",
|
||
"langSlug": "golang",
|
||
"code": "type TextEditor struct {\n\n}\n\n\nfunc Constructor() TextEditor {\n\n}\n\n\nfunc (this *TextEditor) AddText(text string) {\n\n}\n\n\nfunc (this *TextEditor) DeleteText(k int) int {\n\n}\n\n\nfunc (this *TextEditor) CursorLeft(k int) string {\n\n}\n\n\nfunc (this *TextEditor) CursorRight(k int) string {\n\n}\n\n\n/**\n * Your TextEditor object will be instantiated and called as such:\n * obj := Constructor();\n * obj.AddText(text);\n * param_2 := obj.DeleteText(k);\n * param_3 := obj.CursorLeft(k);\n * param_4 := obj.CursorRight(k);\n */",
|
||
"__typename": "CodeSnippetNode"
|
||
},
|
||
{
|
||
"lang": "Ruby",
|
||
"langSlug": "ruby",
|
||
"code": "class TextEditor\n def initialize()\n\n end\n\n\n=begin\n :type text: String\n :rtype: Void\n=end\n def add_text(text)\n\n end\n\n\n=begin\n :type k: Integer\n :rtype: Integer\n=end\n def delete_text(k)\n\n end\n\n\n=begin\n :type k: Integer\n :rtype: String\n=end\n def cursor_left(k)\n\n end\n\n\n=begin\n :type k: Integer\n :rtype: String\n=end\n def cursor_right(k)\n\n end\n\n\nend\n\n# Your TextEditor object will be instantiated and called as such:\n# obj = TextEditor.new()\n# obj.add_text(text)\n# param_2 = obj.delete_text(k)\n# param_3 = obj.cursor_left(k)\n# param_4 = obj.cursor_right(k)",
|
||
"__typename": "CodeSnippetNode"
|
||
},
|
||
{
|
||
"lang": "Scala",
|
||
"langSlug": "scala",
|
||
"code": "class TextEditor() {\n\n def addText(text: String) {\n\n }\n\n def deleteText(k: Int): Int = {\n\n }\n\n def cursorLeft(k: Int): String = {\n\n }\n\n def cursorRight(k: Int): String = {\n\n }\n\n}\n\n/**\n * Your TextEditor object will be instantiated and called as such:\n * var obj = new TextEditor()\n * obj.addText(text)\n * var param_2 = obj.deleteText(k)\n * var param_3 = obj.cursorLeft(k)\n * var param_4 = obj.cursorRight(k)\n */",
|
||
"__typename": "CodeSnippetNode"
|
||
},
|
||
{
|
||
"lang": "Rust",
|
||
"langSlug": "rust",
|
||
"code": "struct TextEditor {\n\n}\n\n\n/**\n * `&self` means the method takes an immutable reference.\n * If you need a mutable reference, change it to `&mut self` instead.\n */\nimpl TextEditor {\n\n fn new() -> Self {\n\n }\n \n fn add_text(&self, text: String) {\n\n }\n \n fn delete_text(&self, k: i32) -> i32 {\n\n }\n \n fn cursor_left(&self, k: i32) -> String {\n\n }\n \n fn cursor_right(&self, k: i32) -> String {\n\n }\n}\n\n/**\n * Your TextEditor object will be instantiated and called as such:\n * let obj = TextEditor::new();\n * obj.add_text(text);\n * let ret_2: i32 = obj.delete_text(k);\n * let ret_3: String = obj.cursor_left(k);\n * let ret_4: String = obj.cursor_right(k);\n */",
|
||
"__typename": "CodeSnippetNode"
|
||
},
|
||
{
|
||
"lang": "Racket",
|
||
"langSlug": "racket",
|
||
"code": "(define text-editor%\n (class object%\n (super-new)\n \n (init-field)\n \n ; add-text : string? -> void?\n (define/public (add-text text)\n )\n ; delete-text : exact-integer? -> exact-integer?\n (define/public (delete-text k)\n )\n ; cursor-left : exact-integer? -> string?\n (define/public (cursor-left k)\n )\n ; cursor-right : exact-integer? -> string?\n (define/public (cursor-right k)\n )))\n\n;; Your text-editor% object will be instantiated and called as such:\n;; (define obj (new text-editor%))\n;; (send obj add-text text)\n;; (define param_2 (send obj delete-text k))\n;; (define param_3 (send obj cursor-left k))\n;; (define param_4 (send obj cursor-right k))",
|
||
"__typename": "CodeSnippetNode"
|
||
},
|
||
{
|
||
"lang": "Erlang",
|
||
"langSlug": "erlang",
|
||
"code": "-spec text_editor_init_() -> any().\ntext_editor_init_() ->\n .\n\n-spec text_editor_add_text(Text :: unicode:unicode_binary()) -> any().\ntext_editor_add_text(Text) ->\n .\n\n-spec text_editor_delete_text(K :: integer()) -> integer().\ntext_editor_delete_text(K) ->\n .\n\n-spec text_editor_cursor_left(K :: integer()) -> unicode:unicode_binary().\ntext_editor_cursor_left(K) ->\n .\n\n-spec text_editor_cursor_right(K :: integer()) -> unicode:unicode_binary().\ntext_editor_cursor_right(K) ->\n .\n\n\n%% Your functions will be called as such:\n%% text_editor_init_(),\n%% text_editor_add_text(Text),\n%% Param_2 = text_editor_delete_text(K),\n%% Param_3 = text_editor_cursor_left(K),\n%% Param_4 = text_editor_cursor_right(K),\n\n%% text_editor_init_ will be called before every test case, in which you can do some necessary initializations.",
|
||
"__typename": "CodeSnippetNode"
|
||
},
|
||
{
|
||
"lang": "Elixir",
|
||
"langSlug": "elixir",
|
||
"code": "defmodule TextEditor do\n @spec init_() :: any\n def init_() do\n \n end\n\n @spec add_text(text :: String.t) :: any\n def add_text(text) do\n \n end\n\n @spec delete_text(k :: integer) :: integer\n def delete_text(k) do\n \n end\n\n @spec cursor_left(k :: integer) :: String.t\n def cursor_left(k) do\n \n end\n\n @spec cursor_right(k :: integer) :: String.t\n def cursor_right(k) do\n \n end\nend\n\n# Your functions will be called as such:\n# TextEditor.init_()\n# TextEditor.add_text(text)\n# param_2 = TextEditor.delete_text(k)\n# param_3 = TextEditor.cursor_left(k)\n# param_4 = TextEditor.cursor_right(k)\n\n# TextEditor.init_ will be called before every test case, in which you can do some necessary initializations.",
|
||
"__typename": "CodeSnippetNode"
|
||
}
|
||
],
|
||
"stats": "{\"totalAccepted\": \"7.5K\", \"totalSubmission\": \"16.9K\", \"totalAcceptedRaw\": 7492, \"totalSubmissionRaw\": 16912, \"acRate\": \"44.3%\"}",
|
||
"hints": [
|
||
"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."
|
||
],
|
||
"solution": null,
|
||
"status": null,
|
||
"sampleTestCase": "[\"TextEditor\",\"addText\",\"deleteText\",\"addText\",\"cursorRight\",\"cursorLeft\",\"deleteText\",\"cursorLeft\",\"cursorRight\"]\n[[],[\"leetcode\"],[4],[\"practice\"],[3],[8],[10],[2],[6]]",
|
||
"metaData": "{\n \"classname\": \"TextEditor\",\n \"constructor\": {\n \"params\": []\n },\n \"methods\": [\n {\n \"params\": [\n {\n \"type\": \"string\",\n \"name\": \"text\"\n }\n ],\n \"name\": \"addText\",\n \"return\": {\n \"type\": \"void\"\n }\n },\n {\n \"params\": [\n {\n \"type\": \"integer\",\n \"name\": \"k\"\n }\n ],\n \"name\": \"deleteText\",\n \"return\": {\n \"type\": \"integer\"\n }\n },\n {\n \"params\": [\n {\n \"type\": \"integer\",\n \"name\": \"k\"\n }\n ],\n \"name\": \"cursorLeft\",\n \"return\": {\n \"type\": \"string\"\n }\n },\n {\n \"params\": [\n {\n \"type\": \"integer\",\n \"name\": \"k\"\n }\n ],\n \"name\": \"cursorRight\",\n \"return\": {\n \"type\": \"string\"\n }\n }\n ],\n \"return\": {\n \"type\": \"boolean\"\n },\n \"systemdesign\": true\n}",
|
||
"judgerAvailable": true,
|
||
"judgeType": "large",
|
||
"mysqlSchemas": [],
|
||
"enableRunCode": true,
|
||
"envInfo": "{\"cpp\":[\"C++\",\"<p>\\u7248\\u672c\\uff1a<code>clang 11<\\/code> \\u91c7\\u7528\\u6700\\u65b0C++ 20\\u6807\\u51c6\\u3002<\\/p>\\r\\n\\r\\n<p>\\u7f16\\u8bd1\\u65f6\\uff0c\\u5c06\\u4f1a\\u91c7\\u7528<code>-O2<\\/code>\\u7ea7\\u4f18\\u5316\\u3002<a href=\\\"https:\\/\\/github.com\\/google\\/sanitizers\\/wiki\\/AddressSanitizer\\\" target=\\\"_blank\\\">AddressSanitizer<\\/a> \\u4e5f\\u88ab\\u5f00\\u542f\\u6765\\u68c0\\u6d4b<code>out-of-bounds<\\/code>\\u548c<code>use-after-free<\\/code>\\u9519\\u8bef\\u3002<\\/p>\\r\\n\\r\\n<p>\\u4e3a\\u4e86\\u4f7f\\u7528\\u65b9\\u4fbf\\uff0c\\u5927\\u90e8\\u5206\\u6807\\u51c6\\u5e93\\u7684\\u5934\\u6587\\u4ef6\\u5df2\\u7ecf\\u88ab\\u81ea\\u52a8\\u5bfc\\u5165\\u3002<\\/p>\"],\"java\":[\"Java\",\"<p>\\u7248\\u672c\\uff1a<code>OpenJDK 17<\\/code>\\u3002\\u53ef\\u4ee5\\u4f7f\\u7528Java 8\\u7684\\u7279\\u6027\\u4f8b\\u5982\\uff0clambda expressions \\u548c stream API\\u3002<\\/p>\\r\\n\\r\\n<p>\\u4e3a\\u4e86\\u65b9\\u4fbf\\u8d77\\u89c1\\uff0c\\u5927\\u90e8\\u5206\\u6807\\u51c6\\u5e93\\u7684\\u5934\\u6587\\u4ef6\\u5df2\\u88ab\\u5bfc\\u5165\\u3002<\\/p>\\r\\n\\r\\n<p>\\u5305\\u542b Pair \\u7c7b: https:\\/\\/docs.oracle.com\\/javase\\/8\\/javafx\\/api\\/javafx\\/util\\/Pair.html <\\/p>\"],\"python\":[\"Python\",\"<p>\\u7248\\u672c\\uff1a <code>Python 2.7.12<\\/code><\\/p>\\r\\n\\r\\n<p>\\u4e3a\\u4e86\\u65b9\\u4fbf\\u8d77\\u89c1\\uff0c\\u5927\\u90e8\\u5206\\u5e38\\u7528\\u5e93\\u5df2\\u7ecf\\u88ab\\u81ea\\u52a8 \\u5bfc\\u5165\\uff0c\\u5982\\uff1a<a href=\\\"https:\\/\\/docs.python.org\\/2\\/library\\/array.html\\\" target=\\\"_blank\\\">array<\\/a>, <a href=\\\"https:\\/\\/docs.python.org\\/2\\/library\\/bisect.html\\\" target=\\\"_blank\\\">bisect<\\/a>, <a href=\\\"https:\\/\\/docs.python.org\\/2\\/library\\/collections.html\\\" target=\\\"_blank\\\">collections<\\/a>\\u3002\\u5982\\u679c\\u60a8\\u9700\\u8981\\u4f7f\\u7528\\u5176\\u4ed6\\u5e93\\u51fd\\u6570\\uff0c\\u8bf7\\u81ea\\u884c\\u5bfc\\u5165\\u3002<\\/p>\\r\\n\\r\\n<p>\\u6ce8\\u610f Python 2.7 <a href=\\\"https:\\/\\/www.python.org\\/dev\\/peps\\/pep-0373\\/\\\" target=\\\"_blank\\\">\\u5c06\\u57282020\\u5e74\\u540e\\u4e0d\\u518d\\u7ef4\\u62a4<\\/a>\\u3002 \\u5982\\u60f3\\u4f7f\\u7528\\u6700\\u65b0\\u7248\\u7684Python\\uff0c\\u8bf7\\u9009\\u62e9Python 3\\u3002<\\/p>\"],\"c\":[\"C\",\"<p>\\u7248\\u672c\\uff1a<code>GCC 8.2<\\/code>\\uff0c\\u91c7\\u7528GNU11\\u6807\\u51c6\\u3002<\\/p>\\r\\n\\r\\n<p>\\u7f16\\u8bd1\\u65f6\\uff0c\\u5c06\\u4f1a\\u91c7\\u7528<code>-O1<\\/code>\\u7ea7\\u4f18\\u5316\\u3002 <a href=\\\"https:\\/\\/github.com\\/google\\/sanitizers\\/wiki\\/AddressSanitizer\\\" target=\\\"_blank\\\">AddressSanitizer<\\/a>\\u4e5f\\u88ab\\u5f00\\u542f\\u6765\\u68c0\\u6d4b<code>out-of-bounds<\\/code>\\u548c<code>use-after-free<\\/code>\\u9519\\u8bef\\u3002<\\/p>\\r\\n\\r\\n<p>\\u4e3a\\u4e86\\u4f7f\\u7528\\u65b9\\u4fbf\\uff0c\\u5927\\u90e8\\u5206\\u6807\\u51c6\\u5e93\\u7684\\u5934\\u6587\\u4ef6\\u5df2\\u7ecf\\u88ab\\u81ea\\u52a8\\u5bfc\\u5165\\u3002<\\/p>\\r\\n\\r\\n<p>\\u5982\\u60f3\\u4f7f\\u7528\\u54c8\\u5e0c\\u8868\\u8fd0\\u7b97, \\u60a8\\u53ef\\u4ee5\\u4f7f\\u7528 <a href=\\\"https:\\/\\/troydhanson.github.io\\/uthash\\/\\\" target=\\\"_blank\\\">uthash<\\/a>\\u3002 \\\"uthash.h\\\"\\u5df2\\u7ecf\\u9ed8\\u8ba4\\u88ab\\u5bfc\\u5165\\u3002\\u8bf7\\u770b\\u5982\\u4e0b\\u793a\\u4f8b:<\\/p>\\r\\n\\r\\n<p><b>1. \\u5f80\\u54c8\\u5e0c\\u8868\\u4e2d\\u6dfb\\u52a0\\u4e00\\u4e2a\\u5bf9\\u8c61\\uff1a<\\/b>\\r\\n<pre>\\r\\nstruct hash_entry {\\r\\n int id; \\/* we'll use this field as the key *\\/\\r\\n char name[10];\\r\\n UT_hash_handle hh; \\/* makes this structure hashable *\\/\\r\\n};\\r\\n\\r\\nstruct hash_entry *users = NULL;\\r\\n\\r\\nvoid add_user(struct hash_entry *s) {\\r\\n HASH_ADD_INT(users, id, s);\\r\\n}\\r\\n<\\/pre>\\r\\n<\\/p>\\r\\n\\r\\n<p><b>2. \\u5728\\u54c8\\u5e0c\\u8868\\u4e2d\\u67e5\\u627e\\u4e00\\u4e2a\\u5bf9\\u8c61\\uff1a<\\/b>\\r\\n<pre>\\r\\nstruct hash_entry *find_user(int user_id) {\\r\\n struct hash_entry *s;\\r\\n HASH_FIND_INT(users, &user_id, s);\\r\\n return s;\\r\\n}\\r\\n<\\/pre>\\r\\n<\\/p>\\r\\n\\r\\n<p><b>3. \\u4ece\\u54c8\\u5e0c\\u8868\\u4e2d\\u5220\\u9664\\u4e00\\u4e2a\\u5bf9\\u8c61\\uff1a<\\/b>\\r\\n<pre>\\r\\nvoid delete_user(struct hash_entry *user) {\\r\\n HASH_DEL(users, user); \\r\\n}\\r\\n<\\/pre>\\r\\n<\\/p>\"],\"csharp\":[\"C#\",\"<p><a href=\\\"https:\\/\\/docs.microsoft.com\\/en-us\\/dotnet\\/csharp\\/whats-new\\/csharp-9\\\" target=\\\"_blank\\\">C# 10<\\/a> \\u8fd0\\u884c\\u5728 .NET 6 \\u4e0a<\\/p>\"],\"javascript\":[\"JavaScript\",\"<p>\\u7248\\u672c\\uff1a<code>Node.js 16.13.2<\\/code><\\/p>\\r\\n\\r\\n<p>\\u60a8\\u7684\\u4ee3\\u7801\\u5728\\u6267\\u884c\\u65f6\\u5c06\\u5e26\\u4e0a <code>--harmony<\\/code> \\u6807\\u8bb0\\u6765\\u5f00\\u542f <a href=\\\"http:\\/\\/node.green\\/\\\" target=\\\"_blank\\\">\\u65b0\\u7248ES6\\u7279\\u6027<\\/a>\\u3002<\\/p>\\r\\n\\r\\n<p><a href=\\\"https:\\/\\/lodash.com\\\" target=\\\"_blank\\\">lodash.js<\\/a> \\u5e93\\u5df2\\u7ecf\\u9ed8\\u8ba4\\u88ab\\u5305\\u542b\\u3002<\\/p>\\r\\n\\r\\n<p> \\u5982\\u9700\\u4f7f\\u7528\\u961f\\u5217\\/\\u4f18\\u5148\\u961f\\u5217\\uff0c\\u60a8\\u53ef\\u4f7f\\u7528 <a href=\\\"https:\\/\\/github.com\\/datastructures-js\\/priority-queue\\/tree\\/fb4fdb984834421279aeb081df7af624d17c2a03\\\" target=\\\"_blank\\\"> datastructures-js\\/priority-queue@5.3.0<\\/a> \\u548c <a href=\\\"https:\\/\\/github.com\\/datastructures-js\\/queue\\/tree\\/e63563025a5a805aa16928cb53bcd517bfea9230\\\" target=\\\"_blank\\\"> datastructures-js\\/queue@4.2.1<\\/a>\\u3002<\\/p>\"],\"ruby\":[\"Ruby\",\"<p>\\u4f7f\\u7528<code>Ruby 3.1<\\/code>\\u6267\\u884c<\\/p>\\r\\n\\r\\n<p>\\u4e00\\u4e9b\\u5e38\\u7528\\u7684\\u6570\\u636e\\u7ed3\\u6784\\u5df2\\u5728 Algorithms \\u6a21\\u5757\\u4e2d\\u63d0\\u4f9b\\uff1ahttps:\\/\\/www.rubydoc.info\\/github\\/kanwei\\/algorithms\\/Algorithms<\\/p>\"],\"swift\":[\"Swift\",\"<p>\\u7248\\u672c\\uff1a<code>Swift 5.5.2<\\/code><\\/p>\\r\\n\\r\\n<p>\\u6211\\u4eec\\u901a\\u5e38\\u4fdd\\u8bc1\\u66f4\\u65b0\\u5230 <a href=\\\"https:\\/\\/swift.org\\/download\\/\\\" target=\\\"_blank\\\">Apple\\u653e\\u51fa\\u7684\\u6700\\u65b0\\u7248Swift<\\/a>\\u3002\\u5982\\u679c\\u60a8\\u53d1\\u73b0Swift\\u4e0d\\u662f\\u6700\\u65b0\\u7248\\u7684\\uff0c\\u8bf7\\u8054\\u7cfb\\u6211\\u4eec\\uff01\\u6211\\u4eec\\u5c06\\u5c3d\\u5feb\\u66f4\\u65b0\\u3002<\\/p>\"],\"golang\":[\"Go\",\"<p>\\u7248\\u672c\\uff1a<code>Go 1.21<\\/code><\\/p>\\r\\n\\r\\n<p>\\u652f\\u6301 <a href=\\\"https:\\/\\/github.com\\/emirpasic\\/gods\\/tree\\/v1.18.1\\\" target=\\\"_blank\\\">https:\\/\\/godoc.org\\/github.com\\/emirpasic\\/gods@v1.18.1<\\/a> \\u7b2c\\u4e09\\u65b9\\u5e93\\u3002<\\/p>\"],\"python3\":[\"Python3\",\"<p>\\u7248\\u672c\\uff1a<code>Python 3.10<\\/code><\\/p>\\r\\n\\r\\n<p>\\u4e3a\\u4e86\\u65b9\\u4fbf\\u8d77\\u89c1\\uff0c\\u5927\\u90e8\\u5206\\u5e38\\u7528\\u5e93\\u5df2\\u7ecf\\u88ab\\u81ea\\u52a8 \\u5bfc\\u5165\\uff0c\\u5982<a href=\\\"https:\\/\\/docs.python.org\\/3\\/library\\/array.html\\\" target=\\\"_blank\\\">array<\\/a>, <a href=\\\"https:\\/\\/docs.python.org\\/3\\/library\\/bisect.html\\\" target=\\\"_blank\\\">bisect<\\/a>, <a href=\\\"https:\\/\\/docs.python.org\\/3\\/library\\/collections.html\\\" target=\\\"_blank\\\">collections<\\/a>\\u3002 \\u5982\\u679c\\u60a8\\u9700\\u8981\\u4f7f\\u7528\\u5176\\u4ed6\\u5e93\\u51fd\\u6570\\uff0c\\u8bf7\\u81ea\\u884c\\u5bfc\\u5165\\u3002<\\/p>\\r\\n\\r\\n<p>\\u5982\\u9700\\u4f7f\\u7528 Map\\/TreeMap \\u6570\\u636e\\u7ed3\\u6784\\uff0c\\u60a8\\u53ef\\u4f7f\\u7528 <a href=\\\"http:\\/\\/www.grantjenks.com\\/docs\\/sortedcontainers\\/\\\" target=\\\"_blank\\\">sortedcontainers<\\/a> \\u5e93\\u3002<\\/p>\"],\"scala\":[\"Scala\",\"<p>\\u7248\\u672c\\uff1a<code>Scala 2.13<\\/code><\\/p>\"],\"kotlin\":[\"Kotlin\",\"<p>\\u7248\\u672c\\uff1a<code>Kotlin 1.9.0<\\/code><\\/p>\\r\\n\\r\\n<p>\\u6211\\u4eec\\u4f7f\\u7528\\u7684\\u662f JetBrains \\u63d0\\u4f9b\\u7684 experimental compiler\\u3002\\u5982\\u679c\\u60a8\\u8ba4\\u4e3a\\u60a8\\u9047\\u5230\\u4e86\\u7f16\\u8bd1\\u5668\\u76f8\\u5173\\u7684\\u95ee\\u9898\\uff0c\\u8bf7\\u5411\\u6211\\u4eec\\u53cd\\u9988<\\/p>\"],\"rust\":[\"Rust\",\"<p>\\u7248\\u672c\\uff1a<code>rust 1.58.1<\\/code><\\/p>\\r\\n\\r\\n<p>\\u652f\\u6301 crates.io \\u7684 <a href=\\\"https:\\/\\/crates.io\\/crates\\/rand\\\" target=\\\"_blank\\\">rand<\\/a><\\/p>\"],\"php\":[\"PHP\",\"<p><code>PHP 8.1<\\/code>.<\\/p>\\r\\n\\r\\n<p>With bcmath module.<\\/p>\"],\"typescript\":[\"TypeScript\",\"<p>TypeScript 5.1.6<\\/p>\\r\\n\\r\\n<p>Compile Options: --alwaysStrict --strictBindCallApply --strictFunctionTypes --target ES2022<\\/p>\\r\\n\\r\\n<p><a href=\\\"https:\\/\\/lodash.com\\\" target=\\\"_blank\\\">lodash.js<\\/a> \\u5e93\\u5df2\\u7ecf\\u9ed8\\u8ba4\\u88ab\\u5305\\u542b\\u3002<\\/p>\\r\\n\\r\\n<p> \\u5982\\u9700\\u4f7f\\u7528\\u961f\\u5217\\/\\u4f18\\u5148\\u961f\\u5217\\uff0c\\u60a8\\u53ef\\u4f7f\\u7528 <a href=\\\"https:\\/\\/github.com\\/datastructures-js\\/priority-queue\\/tree\\/fb4fdb984834421279aeb081df7af624d17c2a03\\\" target=\\\"_blank\\\"> datastructures-js\\/priority-queue@5.3.0<\\/a> \\u548c <a href=\\\"https:\\/\\/github.com\\/datastructures-js\\/queue\\/tree\\/e63563025a5a805aa16928cb53bcd517bfea9230\\\" target=\\\"_blank\\\"> datastructures-js\\/queue@4.2.1<\\/a>\\u3002<\\/p>\"],\"racket\":[\"Racket\",\"<p><a href=\\\"https:\\/\\/docs.racket-lang.org\\/guide\\/performance.html#%28tech._c%29\\\" target=\\\"_blank\\\">Racket CS<\\/a> v8.3<\\/p>\\r\\n\\r\\n<p>\\u4f7f\\u7528 #lang racket<\\/p>\\r\\n\\r\\n<p>\\u5df2\\u9884\\u5148 (require data\\/gvector data\\/queue data\\/order data\\/heap). \\u82e5\\u9700\\u4f7f\\u7528\\u5176\\u5b83\\u6570\\u636e\\u7ed3\\u6784\\uff0c\\u53ef\\u81ea\\u884c require\\u3002<\\/p>\"],\"erlang\":[\"Erlang\",\"Erlang\\/OTP 24.2\"],\"elixir\":[\"Elixir\",\"Elixir 1.13.0 with Erlang\\/OTP 24.2\"],\"dart\":[\"Dart\",\"<p>Dart 2.17.3<\\/p>\\r\\n\\r\\n<p>\\u60a8\\u7684\\u4ee3\\u7801\\u5c06\\u4f1a\\u88ab\\u4e0d\\u7f16\\u8bd1\\u76f4\\u63a5\\u8fd0\\u884c<\\/p>\"]}",
|
||
"book": null,
|
||
"isSubscribed": false,
|
||
"isDailyQuestion": false,
|
||
"dailyRecordStatus": null,
|
||
"editorType": "CKEDITOR",
|
||
"ugcQuestionId": null,
|
||
"style": "LEETCODE",
|
||
"exampleTestcases": "[\"TextEditor\",\"addText\",\"deleteText\",\"addText\",\"cursorRight\",\"cursorLeft\",\"deleteText\",\"cursorLeft\",\"cursorRight\"]\n[[],[\"leetcode\"],[4],[\"practice\"],[3],[8],[10],[2],[6]]",
|
||
"__typename": "QuestionNode"
|
||
}
|
||
}
|
||
} |