leetcode 2296. Design a Text Editor (python)

語言: CN / TW / HK

持續創作,加速成長!這是我參與「掘金日新計劃 · 6 月更文挑戰」的第18天,點選檢視活動詳情

描述

Design a text editor with a cursor that can do the following:

  • Add text to where the cursor is.
  • Delete text from where the cursor is (simulating the backspace key).
  • Move the cursor either left or right.

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.

Follow-up: Could you find a solution with time complexity of O(k) per call?

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.

Note:

1 <= text.length, k <= 40
text consists of lowercase English letters.
At most 2 * 10^4 calls in total will be made to addText, deleteText, cursorLeft and cursorRight.

解析

根據題意,設計一個類,裡面包含了一個初始化函式和四個可以呼叫的函式,這個場景就像我們平時打字一樣:

  • TextEditor() 就是初始化一個空字串
  • void addText(string text) 函式就類似在游標的後面可以加入字元
  • int deleteText(int k) 函式就類似我們按回退鍵,將游標左側的字元進行刪除,但是有可能實際刪除的字元數量小於 k ,因為字串長度有限,所以返回實際刪除的數量
  • string cursorLeft(int k) 類似我們向左邊移動游標,並且返回游標左邊最多 10 個字元
  • string cursorRight(int k) 類似我們向右邊移動游標,並且返回游標左邊最多 10 個字元

結合例子和實際情況,應該很好理解題意,而且題目還提出了更高的要求,每個函式的呼叫的時間複雜度為 O(k) 。

其實這道題不像是 Hard 型別的題目,最多是個 Medium ,我們使用兩個棧 a 和 b 就能解決這個題目,可以想象游標就在這兩個棧的中間(游標其實是個虛擬的字元,不存在也可以解題)。

  • 當呼叫 addText 的時候,我們不斷往棧 a 中新增元素
  • 當呼叫 deleteText 的時候,我們不斷從棧 a 中彈出元素,可能一直彈到沒有,返回實際彈出的元素個數
  • 當呼叫 cursorLeft 的時候,我們 a 棧頂的元素取出來依次壓入 b 中,最後返回 a 最上面的最多 10 個字元
  • 當呼叫 cursorLeft 的時候,我們將 b 棧頂的元素取出來依次壓入 a 中,最後返回 a 最上面的最多 10 個字元

每個函式的時間複雜度為 O(k) 。

解答

class TextEditor:
    def __init__(self):
        self.a, self.b = [], []

    def addText(self, text):
        self.a.extend(list(text))

    def deleteText(self, k):
        tmp = k
        while self.a and tmp:
            self.a.pop()
            tmp -= 1
        return k - tmp

    def cursorLeft(self, k):
        while self.a and k:
            k -= 1
            self.b.append(self.a.pop())
        return ''.join(self.a[-10:])

    def cursorRight(self, k):
        while self.b and k:
            k -= 1
            self.a.append(self.b.pop())
        return ''.join(self.a[-10:])

執行結果

75 / 75 test cases passed.
Status: Accepted
Runtime: 1032 ms
Memory Usage: 39.2 MB

原題連結

https://leetcode.com/contest/weekly-contest-296/problems/design-a-text-editor/

您的支援是我最大的動力