สมมติว่าเรามีสตริง 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