提问人:user22847357 提问时间:11/3/2023 最后编辑:user22847357 更新时间:11/3/2023 访问量:84
如何输出词典上最小的最短的超字符串?
How to output the lexicographically smallest one shortest superstring?
问:
问题是: 给定 n 个字符串 si,并找出最短的字符串 S,使每个 si 都是 S 中的子字符串。 当有多个可能的答案时,输出应该是词典上最小的输出。
例如:testcase:{qgw, qsopd, qwrw, wckumn} 答案应该是“qgwckumnqsopdqwrw”,但我的代码输出是“qgwqsopdqwrwckumn”。 我认为问题出在求解函数中,它没有考虑所有可能的prev字符串。 请帮我找出我应该修改代码的地方,非常感谢!
以下是我的代码:
class Solution {
vector<vector<string>> req;
string merge(string &a, string &b)
{
int n=a.size(), m=b.size(), len=1, idx=0;
while(len<=min(n, m))
{ if(a!=""&&b!=""){
if(a!=b&&b.find(a)!= string::npos)
{ a="";
}
else if(a.substr(n-len)==b.substr(0, len))
{
idx=len;
}
}
len++;
}
string res=b.substr(idx); // idx is distance to non-overlap and res is the non-overlap str
return res;
}
string solve(vector<string> &words, int prev, int mask, int n, vector<vector<string>> &dp)
//prev:parent word, mask:track which word has been selected
{
if(dp[prev][mask]!="") return dp[prev][mask];// check if the dp is empty
string res="";
int minLen=INT_MAX;
for(int i=0; i<n; i++)
{
if(mask&(1<<i)) continue; //check if the i th word has been used
string temp=req[prev][i]+solve(words, i, mask|(1<<i), n, dp);
int temp_size=temp.size();
if(temp_size<minLen)
{
minLen=temp.size();
res=temp;
}
}
return dp[prev][mask]=res;
}
public:
string shortestSuperstring(vector<string>& words)
{
int n=words.size();
sort(words.begin(), words.end());
req.resize(n, vector<string> (n, ""));
vector<vector<string>> dp(n, vector<string> ((1<<(n+1)), ""));
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
if(i==j) continue;
req[i][j]=merge(words[i], words[j]);
}
}
string ans="";
int minLen=INT_MAX;
int mask=0;
for(int i=0; i<n; i++)
{
string temp=words[i]+solve(words, i, mask|(1<<i), n, dp);
cout<<"temp: "<<temp<<"\n";
int temp_size=temp.size();
if(temp_size<minLen)
{
minLen=temp.size();
ans=temp;
}
}
return ans;
}
};
答:
2赞
Kozydot
11/3/2023
#1
现有代码中的主要问题是,当存在多种可能性时,它没有考虑词典上最小的要求。它只考虑字符串长度。
您可以对代码进行一些修改以解决此问题:
- 更改函数以返回一对整数:
重叠部分的长度和第二个字符串的索引。
这将允许您跟踪词典顺序。
merge
- 在您的函数中,当与 、
还要考虑长度相等时的词典顺序。
您可以通过向 if 添加辅助条件来实现此目的
这样的陈述:
solve
temp_size
minLen
if(temp_size < minLen || (temp_size == minLen && temp < res))
{
minLen = temp_size;
res = temp;
}
- 在函数中,同样添加辅助函数
考虑词典顺序的条件:
shortestSuperstring
if(temp_size < minLen || (temp_size == minLen && temp < ans))
{
minLen = temp_size;
ans = temp;
}
评论
1赞
user22847357
11/3/2023
谢谢~我添加了次要条件,它通过了!!
评论