583 兩個字串的刪除操作

2022-09-08 08:15:13 字數 1599 閱讀 4541

給定兩個單詞 word1 和 word2,找到使得 word1 和 word2 相同所需的最小步數,每步可以刪除任意乙個字串中的乙個字元。

示例:輸入: "sea", "eat"

輸出: 2

解釋: 第一步將"sea"變為"ea",第二步將"eat"變為"ea"

這次是兩個字串可以相互刪了,這種題目也知道用動態規劃的思路來解,動規五部曲,分析如下:

確定dp陣列(dp table)以及下標的含義

dp[i][j]:以i-1為結尾的字串word1,和以j-1位結尾的字串word2,想要達到相等,所需要刪除元素的最少次數。

這裡dp陣列的定義有點點繞,大家要擼清思路。

確定遞推公式

當word1[i - 1] 與 word2[j - 1]相同的時候,dp[i][j] = dp[i - 1][j - 1];

當word1[i - 1] 與 word2[j - 1]不相同的時候,有三種情況:

情況一:刪word1[i - 1],最少操作次數為dp[i - 1][j] + 1

情況二:刪word2[j - 1],最少操作次數為dp[i][j - 1] + 1

情況三:同時刪word1[i - 1]和word2[j - 1],操作的最少次數為dp[i - 1][j - 1] + 2

那最後當然是取最小值,所以當word1[i - 1] 與 word2[j - 1]不相同的時候,遞推公式:dp[i][j] = min();

dp陣列如何初始化

從遞推公式中,可以看出來,dp[i][0] 和 dp[0][j]是一定要初始化的。

dp[i][0]:word2為空字串,以i-1為結尾的字串word2要刪除多少個元素,才能和word1相同呢,很明顯dp[i][0] = i。

dp[0][j]的話同理,所以**如下:

vector> dp(word1.size() + 1, vector(word2.size() + 1));

for (int i = 0; i <= word1.size(); i++) dp[i][0] = i;

for (int j = 0; j <= word2.size(); j++) dp[0][j] = j;

確定遍歷順序

從遞推公式 dp[i][j] = min(dp[i - 1][j - 1] + 2, min(dp[i - 1][j], dp[i][j - 1]) + 1); 和dp[i][j] = dp[i - 1][j - 1]可以看出dp[i][j]都是根據左上方、正上方、正左方推出來的。

所以遍歷的時候一定是從上到下,從左到右,這樣保證dp[i][j]可以根據之前計算出來的數值進行計算。

舉例推導dp陣列

以word1:"sea",word2:"eat"為例,推導dp陣列狀態圖如下:

583 兩個字串的刪除操作

給定兩個單詞 word1 和 word2,找到使得 word1 和 word2 相同所需的最小步數,每步可以刪除任意乙個字串中的乙個字元。示例 1 說明 1.給定單詞的長度不超過500。2.給定單詞中的字元只含有小寫字母。為了求得最少刪除次數,我們可以求出串 s1和串 s2最長公共子串行,我們記為 ...

583 兩個字串的刪除操作

題目描述 給定兩個單詞 word1 和 word2,找到使得 word1 和 word2 相同所需的最小步數,每步可以刪除任意乙個字串中的乙個字元。解題思路 動態規劃,和最長公共子串行相似,根據當前結尾的兩個字元是否相等選擇不同的轉移方式,如下 class solution def mindista...

583 兩個字串的刪除操作

題目描述 給定兩個單詞 word1 和 word2,找到使得 word1 和 word2 相同所需的最小步數,每步可以刪除任意乙個字串中的乙個字元。示例 輸入 sea eat 輸出 2 解釋 第一步將 sea 變為 ea 第二步將 eat 變為 ea 給定單詞的長度不超過500。給定單詞中的字元只含...