สมมติว่าเรามีสตริง str1 และ str2 สองสตริง เราต้องหาสตริงที่สั้นที่สุดที่มีทั้ง str1 และ str2 เป็นลำดับรอง อาจมีมากกว่าหนึ่งผลลัพธ์ ดังนั้นเราจะส่งคืนผลลัพธ์เพียงรายการเดียวเท่านั้น
ดังที่คุณทราบสตริง S ถูกเรียกว่าเป็นผลสืบเนื่องของสตริง T หากการลบอักขระบางตัวออกจาก T (อาจเป็น 0 และเลือกอักขระที่ใดก็ได้จาก T) ผลลัพธ์ในสตริง S
ดังนั้น หากอินพุตเป็นเหมือน "acab", "bac" ผลลัพธ์จะเป็น "bacab" นั่นเป็นเพราะว่าสองสตริงที่ให้มานั้นเป็นส่วนรองของสิ่งนี้
เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -
-
กำหนดฟังก์ชัน getLCS() ซึ่งจะใช้เวลา s1, s2
-
ret :=สตริงว่าง
-
n :=ขนาดของ s1, m :=ขนาดของ s2
-
กำหนดขนาดอาร์เรย์ 2 มิติหนึ่ง dp (n + 1) x (m + 1)
-
ผม :=น, เจ :=ม.
-
s1 :=เชื่อมสตริงว่างก่อน s1
-
s2 :=เชื่อมสตริงว่างก่อน s2
-
สำหรับการเริ่มต้น i :=1 เมื่อฉัน <=n อัปเดต (เพิ่ม i ขึ้น 1) ทำ -
-
สำหรับการเริ่มต้น j :=1 เมื่อ j <=m อัปเดต (เพิ่ม j ขึ้น 1) ทำ −
-
ถ้า s1[i] เหมือนกับ s2[j] แล้ว −
-
dp[i, j] :=1 + dp[i - 1, j - 1]
-
-
มิฉะนั้น
-
dp[i, j] :=สูงสุดของ dp[i - 1, j] และ dp[i, j - 1]
-
-
-
-
ในขณะที่ (i ไม่ใช่ศูนย์และ j ไม่ใช่ศูนย์) ทำ -
-
ถ้า dp[i, j] เหมือนกับ dp[i - 1, j] แล้ว −
-
(ลดลง 1)
-
ละเว้นส่วนต่อไปนี้ ข้ามไปยังการทำซ้ำถัดไป
-
-
ถ้า dp[i, j] เหมือนกับ dp[i, j - 1] แล้ว −
-
(ลด j โดย 1)
-
ละเว้นส่วนต่อไปนี้ ข้ามไปยังการทำซ้ำถัดไป
-
-
ret :=ret + s1[i]
-
(ลดลง 1)
-
(ลด j โดย 1)
-
-
ย้อนกลับอาร์เรย์ ret
-
รีเทิร์น
-
จากวิธีหลัก ให้ทำดังต่อไปนี้ −
-
s3 :=getLCS(str1, str2)
-
ret :=สตริงว่าง i :=0, j :=0, k :=0
-
ในขณะที่ k <ขนาดของ s3 ทำ −
-
ถ้าฉัน <ขนาดของ str1 และ str1[i] ไม่เท่ากับ s3[k] ดังนั้น −
-
ret :=ret + str1[i]
-
(เพิ่ม i ขึ้น 1)
-
ละเว้นส่วนต่อไปนี้ ข้ามไปยังการทำซ้ำถัดไป
-
-
ถ้า j <ขนาดของ str2 และ str2[j] ไม่เท่ากับ s3[k] ดังนั้น −
-
ret :=ret + str2[j]
-
(เพิ่มขึ้น j โดย 1)
-
ละเว้นส่วนต่อไปนี้ ข้ามไปยังการทำซ้ำถัดไป
-
-
ret :=ret + s3[k]
-
(เพิ่ม i, j, k ขึ้น 1)
-
-
ในขณะที่ฉัน <ขนาดของ str1 ทำ −
-
ret :=ret + str1[i]
-
(เพิ่ม i ขึ้น 1)
-
-
ในขณะที่ j <ขนาดของ str2 ทำ −
-
ret :=ret + str2[j]
-
(เพิ่มขึ้น j โดย 1)
-
-
รีเทิร์น
ให้เราดูการใช้งานต่อไปนี้เพื่อความเข้าใจที่ดีขึ้น -
ตัวอย่าง
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
string shortestCommonSupersequence(string str1, string str2){
string s3 = getLCS(str1, str2);
string ret = "";
int i = 0;
int j = 0;
int k = 0;
while (k < s3.size()) {
if (i < str1.size() && str1[i] != s3[k]) {
ret += str1[i];
i++;
continue;
}
if (j < str2.size() && str2[j] != s3[k]) {
ret += str2[j];
j++;
continue;
}
ret += s3[k];
k++;
i++;
j++;
}
while (i < str1.size()) {
ret += str1[i];
i++;
}
while (j < str2.size()) {
ret += str2[j];
j++;
}
return ret;
}
string getLCS(string s1, string s2){
string ret = "";
int n = s1.size();
int m = s2.size();
vector<vector<int> > dp(n + 1, vector<int>(m + 1));
int i = n;
int j = m;
s1 = " " + s1;
s2 = " " + s2;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (s1[i] == s2[j]) {
dp[i][j] = 1 + dp[i - 1][j - 1];
} else {
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
while (i && j) {
if (dp[i][j] == dp[i - 1][j]) {
i--;
continue;
}
if (dp[i][j] == dp[i][j - 1]) {
j--;
continue;
}
ret += s1[i];
i--;
j--;
}
reverse(ret.begin(), ret.end());
return ret;
}
};
main(){
Solution ob;
cout << (ob.shortestCommonSupersequence("acab", "bac"));
} อินพุต
"acab", "bac"
ผลลัพธ์
bacab