目錄
最長公共子串行【leetcode 1143】
最長公共子陣列【leetcode 718】
編輯距離1:支援替換+交換【360筆試題 2020.3.24】
編輯距離2:支援移動字元到末尾【阿里筆試題 2020.3.27】
給定兩個字串text1
和text2
,返回這兩個字串的最長公共子串行。
【思路】動態規劃。dp[i][j]表示s1[0..i) 和 s2[0..j)的最長公共子串行(lcs) 長度輸入:text1 = "abcde", text2 = "ace"
輸出:3
解釋:最長公共子串行是 "ace",它的長度為 3。
狀態轉移方程:
若dp[i-1] == dp[j-1], 則dp[i][j] = dp[i-1][j-1] + 1
若dp[i-1] != dp[j-1], 則dp[i][j] = max(dp[i-1][j], dp[i][j-1])
給兩個整數陣列a
和b
,返回兩個陣列中公共的、長度最長的子陣列的長度。
【思路】動態規劃。dp[i][j]表示以a[i]和b[j]為結尾的公共子陣列的最長長度(必須包含a[i]和b[j])。輸入:
a: [1,2,3,2,1]
b: [3,2,1,4,7]
輸出: 3
解釋:
長度最長的公共子陣列是 [3, 2, 1]。
狀態轉移方程:
當a[i] != b[j],dp[i][j] = 0, 因為它們的末尾元素a[i]和b[j]不等,因此以a[i]和b[j]結尾的公共子陣列不存在。
當a[i] == b[j],dp[i][j] = dp[i-1][j-1]+1
兩個字串a和b,長度相等,並且只有a和t兩種字元。通過2種操作把a變成b,求最少操作次數。
第1種操作,替換乙個字元
第2種操作,交換兩個字元的位置
示例:
輸入:
taaatt
aattaa
輸出:3
解釋:把第1個字元t替換為a,第3、5個字元交換,第4、6個字元交換。
【思路】這題類似於編輯距離,但操作不同,總體要簡單些,不需要dp。
因為兩個字串長度相等,所以只需要對字元不同的位進行操作。
又因為只有兩種字元a和t,所以字元不同時只有2種配對情況:a的位上是a而b的位上是t,簡記為a-t;另一種就是t-a。
分別用cnt1,cnt2統計這兩種情況的數量,那麼最少操作次數就是 max(cnt1,cnt2)。
證明:不妨設cnt1 > cnt2(另一種情況同理),即有cnt1個位置是a-t,cnt2個位置是t-a
那麼我們可以先把 cnt2 個t-a 和 cnt2 個a-t進行交換,需要 cnt2 次交換操作。
這樣就只剩 cnt1 - cnt2 個a-t了(其他位置上的字元都相同),需要進行 cnt1 - cnt2 次替換操作。
所以總次數為 cnt2 + ( cnt1 - cnt2) = cnt1,即cnt1和cnt2中較大的那個數。
int main()
cout給定兩個長度相同的小寫字串s1和s2,要將s1轉換為s2,每次可以將s1中的任意乙個字元移動到s1的末尾。
求最少操作次數。如果不能轉換,則返回-1。
樣例:
輸入
ackdm
ckadm
輸出
【思路】
首先,這題和最長公共子串行沒有關係。樣例中最長公共子串行的長度是4,照這樣算移動次數應是5-4=1,但實際上要移動3次。
實際上這道題是貪心,是找s2的最長字首使得s1中存在子串行與其匹配。因為 s1 每次挑的字元都要放到末尾,因此s2 的字首應該盡可能和 s1 的子串行相匹配。
實現時使用兩個指標指向兩個字串,如果當前字元不同則次數加1,s1的指標後移1位;如果字元相同就都後移1位。最後,s2 指標的位置就是盡可能匹配的最長字首了。
dp專題 最長公共子串行
最長公共子串行 題目描述 乙個給定序列的子串行是在該序列中刪去若干元素後得到的序列。確切地說,若給定序列x1,x2,x,則另一串行z1,z2,zk是x的子串行是指存在乙個嚴格遞增的下標序列使得對於所有j 1,2,k有 x例如,序列zb,c,d,b是序列xa,b,c,b,d,a,b的子串行,相應的遞增...
最長公共子串行 最長公共子串
1 最長公共子串行 採用動態規劃的思想,用乙個陣列dp i j 記錄a字串中i 1位置到b字串中j 1位置的最長公共子串行,若a i 1 b j 1 那麼dp i j dp i 1 j 1 1,若不相同,那麼dp i j 就是dp i 1 j 和dp i j 1 中的較大者。class lcs el...
最長公共子串行 最長公共子串
1.區別 找兩個字串的最長公共子串,這個子串要求在原字串中是連續的。而最長公共子串行則並不要求連續。2 最長公共子串 其實這是乙個序貫決策問題,可以用動態規劃來求解。我們採用乙個二維矩陣來記錄中間的結果。這個二維矩陣怎麼構造呢?直接舉個例子吧 bab 和 caba 當然我們現在一眼就可以看出來最長公...