मान लीजिए कि हमारे पास दो तार S और T हैं। हमें संचालन का सबसे छोटा अनुक्रम खोजना है जो S को T में बदलता है। यहां संचालन मूल रूप से या तो हटा रहा है या एक वर्ण सम्मिलित कर रहा है।
इसलिए, यदि इनपुट S ="xxxy" T ="xxyy" जैसा है, तो आउटपुट ["x", "x", "-x", "y", "+y"] होगा, इसका अर्थ है स्थान पहले दो x, फिर तीसरा x निकालें, फिर y रखें और फिर एक नया y जोड़ें।
इसे हल करने के लिए, हम इन चरणों का पालन करेंगे -
- 505 x 505 आकार की एक टेबल डीपी बनाएं
- एक फ़ंक्शन सहायता परिभाषित करें (), इसमें i, j, S, T, लगेगा
- यदि i, S के आकार के समान है और j, T के आकार के समान है, तो −
- रिटर्न डीपी[i, j] =0
- यदि i, S के आकार के समान है, तो −
- रिटर्न डीपी[i, j] =1 + सहायता (i, j + 1, S, T)
- यदि j, T के आकार के समान है, तो −
- रिटर्न डीपी[i, j] =1 + सहायता (i + 1, j, S, T)
- यदि dp[i, j] -1 के बराबर नहीं है, तो −
- रिटर्न डीपी[i, j]
- न करें:=1e5, डेल:=0, सम्मिलित करें:=0
- यदि S[i], T[j] के समान है, तो −
- न करें:=सहायता (i + 1, j + 1, S, T)
- del :=1 + सहायता (i + 1, j, S, T)
- सम्मिलित करें:=1 + सहायता(i, j + 1, S, T)
- minVal:=min({dontDo, del, insert})
- रिटर्न डीपी[i, j] =minVal
- एक फ़ंक्शन को परिभाषित करें getPath(), इसमें i, j, S, T, curr, एक सरणी रेट, लगेगा
- यदि curr 0 के समान है और i, S के आकार के समान है और j, T के आकार के समान है, तो −
- वापसी
- यदि मैं <एस का आकार और जे <टी और एस का आकार [i] टी [जे] और डीपी [i + 1, j + 1] के समान है, तो −
- रिटर्न के अंत में स्ट्रिंग(1, एस[i]) डालें
- getPath(i + 1, j + 1, S, T, curr, ret)
- अन्यथा जब dp[i + 1, j] + 1 curr के समान हो, तो −
- रिट के अंत में
- सम्मिलित करें ("-" स्ट्रिंग को संयोजित करें(1, S[i]))
- getPath(i + 1, j, S, T, curr-1, ret)
- अन्यथा
- रिट के अंत में
- सम्मिलित करें ("+" स्ट्रिंग को संयोजित करें(1, T[j]))
- getPath(i, j + 1, S, T, curr-1, ret)
- मुख्य विधि से निम्न कार्य करें -
- डीपी को -1 से भरें
- एक सरणी रिट परिभाषित करें
- x :=सहायता (0, 0, एस, टी)
- getPath(0, 0, S, T, x, ret)
- रिटर्न रिटर्न
उदाहरण (C++)
आइए बेहतर समझ पाने के लिए निम्नलिखित कार्यान्वयन देखें -
#include <bits/stdc++.h>
using namespace std;
void print_vector(vector<auto> v) {
cout << "[";
for (int i = 0; i < v.size(); i++) {
cout << v[i] << ", ";
}
cout << "]" << endl;
}
int dp[505][505];
class Solution {
public:
int help(int i, int j, string& S, string& T) {
if (i == S.size() && j == T.size())
return dp[i][j] = 0;
if (i == S.size())
return dp[i][j] = 1 + help(i, j + 1, S, T);
if (j == T.size())
return dp[i][j] = 1 + help(i + 1, j, S, T);
if (dp[i][j] != -1)
return dp[i][j];
int dontDo = 1e5;
int del = 0;
int insert = 0;
if (S[i] == T[j])
dontDo = help(i + 1, j + 1, S, T);
del = 1 + help(i + 1, j, S, T);
insert = 1 + help(i, j + 1, S, T);
int minVal = min({dontDo, del, insert});
return dp[i][j] = minVal;
}
void getPath(int i, int j, string& S, string& T, int curr, vector<string>& ret) {
if (curr == 0 && i == S.size() && j == T.size())
return;
if (i < S.size() && j < T.size() && S[i] == T[j] && dp[i + 1][j + 1] == curr) {
ret.push_back(string(1, S[i]));
getPath(i + 1, j + 1, S, T, curr, ret);
}else if (dp[i + 1][j] + 1 == curr) {
ret.push_back("-" + string(1, S[i]));
getPath(i + 1, j, S, T, curr - 1, ret);
}else {
ret.push_back("+" + string(1, T[j]));
getPath(i, j + 1, S, T, curr - 1, ret);
}
}
vector<string> solve(string S, string T) {
memset(dp, -1, sizeof dp);
vector<string> ret;
int x = help(0, 0, S, T);
getPath(0, 0, S, T, x, ret);
return ret;
}
};
vector<string> solve(string source, string target) {
return (new Solution())->solve(source, target);
}
main(){
string S = "xxxy", T = "xxyy";
print_vector(solve(S, T));
} इनपुट
"xxxy", "xxyy"
आउटपुट
[x, x, -x, y, +y, ]