字串DP: 用最少的操作次數生成字串_2 Keys Keyboard_Leetcode #650

小松鼠-avatar-img
發佈於演算法題目解析 個房間
更新於 發佈於 閱讀時間約 8 分鐘

題目敘述 Leetcode: 650. 2 Keys Keyboard


一開始初始化的時候,記事本上只有一個字元'A'

只允許下列兩種操作

  1. 複製目前記事本上的整個字串
  2. 貼上之前複製的內容,串接在尾端。


請問,最少需要幾個操作,
才能製造出內容都是 "AAA...A",長度為n,內部每個字元都是'A'的字串?


測試範例

Example 1:

Input: n = 3
Output: 3
Explanation:

一開始,初始字串是A
第一步,複製整個字串A
第二步,貼上A,內容變成AA
第三步,貼上A,內容變成AAA

任務完成,最少需要三步,來生成長度為3,內部每個字元都是'A'的字串"AAA"


Example 2:

Input: n = 1
Output: 0

一開始,初始字串是A
所需步數為零步。​

約束條件

Constraints:

  • 1 <= n <= 1000

n介於1~1000之間。


觀察 試著從小單元複製貼上,精簡步數。


假如n不是質數的時候,
可以試著從更小的小單元(小單元的長度是n的因數)複製貼上,製造出長度為n的字串。


例如: 當n=4時

初始化是A

第一步 複製A

第二步 貼上A,整個字串現在是"AA"

第三步 複製"AA"

第四步 貼上A,整個字串現在是"AAAA"


例如: 當n=6時

初始化是A

第一步,複製A。

第二步,貼上A,整個字串現在是"AA"。

第三步,,貼上A,整個字串現在是"AAA"。

第四步,複製AAA。

第五步,貼上AAA,整個字串現在是"AAAAAA"。


假如n是質數的時候,
代表無法從更小的小單元(小單元的長度是n的因數)複製貼上,製造出長度為n的字串。

只能從A開始一個字元一個字元慢慢貼上。


例如: 當n=3時

初始化是A

第一步,複製A。

第二步,貼上A,整個字串現在是"AA"。

第三步,貼上A,整個字串現在是"AAA"。


例如: 當n=5時

初始化是A

第一步,複製A。

第二步,貼上A,整個字串現在是"AA"。

第三步,貼上A,整個字串現在是"AAA"。

第四步,貼上A,整個字串現在是"AAAA"。

第五步,貼上A,整個字串現在是"AAAAA"。


演算法 字串DP


怎麼定義DP狀態?

定義 DP[ i ] 代表長度為 i 的字串,所需要的最少操作數目。

最後所求就是DP[ n ]


怎麼推導DP狀態轉移關係式?


i 不是質數時,
可以化簡到長度為因數的更小字串,依靠複製貼上,來製造長度為 i的字串。

DP[ i ] = min{ DP[ i // j ] + 1次複製 + (j-1)次貼上, 而且i 是 j 的倍數 }

DP[ i ] = min{ DP[ i // j ] + j, 而且 i 是 j 的倍數 }


最後可以寫成如下的形式( % 代表作除法,取餘數的意思)

DP[ i ] = min{ DP[ i // j ] + j, 而且 i % j == 0 }



i 是質數的時候,

代表無法從更小的小單元(小單元的長度是n的因數)複製貼上,製造出長度為n的字串。

只能從A開始一個字元一個字元慢慢貼上。

DP[ i ] = 1次複製 + (i-1)次貼上 = i 次操作


最後可以寫成如下的形式

DP[ i ] = i


初始條件(終止條件)為何?


最小規模的問題是

i = 1時,剛好是初始化狀態A,不用任何操作,此時DP[ 1 ] = 0

i = 2時,剛好是初始化狀態A,接著複製A一次,再貼上A一次,此時DP[ 2 ] = 2



程式碼 字串DP

class Solution:
def minSteps(self, n: int) -> int:

# helper lambda function to check if x is multiple of y or not
is_divisible = lambda x, y: x % y == 0

table = {}
def dp(i):

if i in table:
return table[i]

if i == 1:

# Base case:
# "A" is given by initial condition, no extra cost.
table[1] = 0
return 0

elif i == 2:

# Base case:
# "AA" is reached by copy "A" and paste "A"
table[2] = 2
return 2

else:
## General cases:

# Usual case, if i is NOT prime number, we can find a shrink factor F of i, which i is divisible by F, allow us to grow from smaller string by copy-and-paste

# the length of smaller string being copied = i / F
# cost of copy: 1
# cost of paste: F - 1

# total cost = DP[ i / F ] + cost of copy + cost of paste = DP[ i / F ] + 1 + F - 1 = DP[ i / F ] + F

# Worst cast, if i is prime number,
# then "AAA...A" with length i can only reached by copy "A" and paste (i-1) times, total cost = 1 + (i-1) = i

table[i] = min( [i] + [dp(i//factor) + factor for factor in range(2, int(i**0.5)+1 ) if is_divisible(i, factor)] )
return table[i]

# ---------------------------------------------------

return dp(n)


複雜度分析

時間複雜度:O(n^1.5)

雙層迭代,外層迭代index i,內層迭代factor,O(n) * O(n^0.5) = O(n^1.5)


空間複雜度: O(n)

需要建立一個DP table,所需空間為O(n)


Reference:

[1] 2 Keys Keyboard - LeetCode

留言
avatar-img
留言分享你的想法!
小松鼠-avatar-img
發文者
2024/08/19
林燃(創作小說家)
avatar-img
小松鼠的演算法樂園
96會員
427內容數
由有業界實戰經驗的演算法工程師, 手把手教你建立解題的框架, 一步步寫出高效、清晰易懂的解題答案。 著重在讓讀者啟發思考、理解演算法,熟悉常見的演算法模板。 深入淺出地介紹題目背後所使用的演算法意義,融會貫通演算法與資料結構的應用。 在幾個經典的題目融入一道題目的多種解法,或者同一招解不同的題目,擴展廣度,並加深印象。
2024/09/13
給定一個整數陣列arr,和一串區間XOR請求queries。 請計算queries所請求的區間XOR值,並且以陣列的形式返回答案。
Thumbnail
2024/09/13
給定一個整數陣列arr,和一串區間XOR請求queries。 請計算queries所請求的區間XOR值,並且以陣列的形式返回答案。
Thumbnail
2024/08/27
Path with Maximum Probability 題目給定一個無向圖(雙向移動皆可), 提供每條邊的起終點,和每條邊對應的通過時的成功機率。 請問從起點start走到終點end的最高成功機率是多少? 如果完全沒有路徑可以抵達,則返回0。
Thumbnail
2024/08/27
Path with Maximum Probability 題目給定一個無向圖(雙向移動皆可), 提供每條邊的起終點,和每條邊對應的通過時的成功機率。 請問從起點start走到終點end的最高成功機率是多少? 如果完全沒有路徑可以抵達,則返回0。
Thumbnail
2024/08/21
題目敘述 664. Strange Printer 有一台奇怪的印表機, 每次操作只能連續印同樣的字母,但是列印的長度可以自由控制。 而且,印刷的時候,可以蓋過去舊的字元。 (這邊當然不合常理,讀者可以理解成塗了立可帶再蓋過去的情境) 給定一個輸入字串s,請問最少需要幾次操作,才能印出字串s?
Thumbnail
2024/08/21
題目敘述 664. Strange Printer 有一台奇怪的印表機, 每次操作只能連續印同樣的字母,但是列印的長度可以自由控制。 而且,印刷的時候,可以蓋過去舊的字元。 (這邊當然不合常理,讀者可以理解成塗了立可帶再蓋過去的情境) 給定一個輸入字串s,請問最少需要幾次操作,才能印出字串s?
Thumbnail
看更多
你可能也想看
Thumbnail
全球科技產業的焦點,AKA 全村的希望 NVIDIA,於五月底正式發布了他們在今年 2025 第一季的財報 (輝達內部財務年度為 2026 Q1,實際日曆期間為今年二到四月),交出了打敗了市場預期的成績單。然而,在銷售持續高速成長的同時,川普政府加大對於中國的晶片管制......
Thumbnail
全球科技產業的焦點,AKA 全村的希望 NVIDIA,於五月底正式發布了他們在今年 2025 第一季的財報 (輝達內部財務年度為 2026 Q1,實際日曆期間為今年二到四月),交出了打敗了市場預期的成績單。然而,在銷售持續高速成長的同時,川普政府加大對於中國的晶片管制......
Thumbnail
題目敘述: 給定一個傳統手機鍵盤,如圖所示 接著給定一個字串word。 現在讓你重新安排每個字母的所在位置,每個字母可以重新安排到2~9這幾個鍵盤上的位置,每個字母限定只能選擇一個數字鍵去對應。 請問重新安排之後,最少要幾次按鍵才能輸出字串word?
Thumbnail
題目敘述: 給定一個傳統手機鍵盤,如圖所示 接著給定一個字串word。 現在讓你重新安排每個字母的所在位置,每個字母可以重新安排到2~9這幾個鍵盤上的位置,每個字母限定只能選擇一個數字鍵去對應。 請問重新安排之後,最少要幾次按鍵才能輸出字串word?
Thumbnail
題目要求計算兩個二進位字串的相加,並以字串的形式輸出。 字串內容只包含'0'或'1'字元。 複雜度分析 時間複雜度為O(m+n),空間複雜度為O(m+n)。
Thumbnail
題目要求計算兩個二進位字串的相加,並以字串的形式輸出。 字串內容只包含'0'或'1'字元。 複雜度分析 時間複雜度為O(m+n),空間複雜度為O(m+n)。
Thumbnail
題目敘述 Minimum Deletions to Make String Balanced 給定一個只會有包含'a'b或'b'的輸入字串s。 每次操作可以任選一個字元刪除。 請問最少需要多少次操作,才會使得所有的'b'都在'a'後面? 測試範例 Example 1: Input: s
Thumbnail
題目敘述 Minimum Deletions to Make String Balanced 給定一個只會有包含'a'b或'b'的輸入字串s。 每次操作可以任選一個字元刪除。 請問最少需要多少次操作,才會使得所有的'b'都在'a'後面? 測試範例 Example 1: Input: s
Thumbnail
Append Characters to String to Make Subsequence 給定兩個字串s和字串t。 請計算最少的字元串接數量是多少,串接在s的尾端,使得t是s的子序列。 測試範例 Example 1: Input: s = "coaching", t =
Thumbnail
Append Characters to String to Make Subsequence 給定兩個字串s和字串t。 請計算最少的字元串接數量是多少,串接在s的尾端,使得t是s的子序列。 測試範例 Example 1: Input: s = "coaching", t =
Thumbnail
題目敘述 題目會給定我們兩個字串word1 和 word2。 允許我們不限制次數進行下列兩種操作: 任意調換其中兩個字元的位置。 把字串中的某個字元全部置換成另一個字元,同時把另一個字元同時置換成某個字元。(例如把字串中原本的a都換成b,把原本的b都換成a) 問我們能不能通過上述兩項操作,
Thumbnail
題目敘述 題目會給定我們兩個字串word1 和 word2。 允許我們不限制次數進行下列兩種操作: 任意調換其中兩個字元的位置。 把字串中的某個字元全部置換成另一個字元,同時把另一個字元同時置換成某個字元。(例如把字串中原本的a都換成b,把原本的b都換成a) 問我們能不能通過上述兩項操作,
Thumbnail
題目敘述 題目會給我們兩個字串作為輸入,分別是字串s和字串t,問我最少要做幾次字元轉換,讓字串t和字串s成為Anagram"同字母異序詞"? 註: 例如 god 和 dog 就是 Anagram 同字母異序詞,也是就說,組成字母相同,但是順序可以重新排列。 題目的原文敘述 測試範例 Ex
Thumbnail
題目敘述 題目會給我們兩個字串作為輸入,分別是字串s和字串t,問我最少要做幾次字元轉換,讓字串t和字串s成為Anagram"同字母異序詞"? 註: 例如 god 和 dog 就是 Anagram 同字母異序詞,也是就說,組成字母相同,但是順序可以重新排列。 題目的原文敘述 測試範例 Ex
Thumbnail
題目會給我們一個字串陣列nums,內容都是二進位字串,要求我們造出一個另一個相等長度,新的二進位字串,而且不和字串陣列nums內的重複。 答案可能有不只一組,回傳合任一組合法的答案皆可。
Thumbnail
題目會給我們一個字串陣列nums,內容都是二進位字串,要求我們造出一個另一個相等長度,新的二進位字串,而且不和字串陣列nums內的重複。 答案可能有不只一組,回傳合任一組合法的答案皆可。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News