Я решал проблему, когда сталкивался с довольно простой проблемой. Учитывая две строки S1
и S2
, merge(S1,S2)
обозначает любую строку, полученную путем перемешивания двух строк S1
и S2
, сохраняя порядок символов в обоих случаях, чтобы результирующая строка была лексикографически наименьшей.Объединить две строки и создать лексикографическую наименьшую объединенную строку
Пример
S1 = abad
S2 = bbde
merge(S1, S2) = ababbdde
Теперь, я попытался решить проблему путем применения жадного техники, начиная с первого элемента как строки, а затем ищет наименьшего элемента и добавить его к результату. Но вскоре я узнал, что это не всегда приводит к оптимальному решению. Код выглядел примерно так.
int n = a.size(), m = b.size();
int i =0, j=0, k=0; char array[n+m];
for(; i< n && j<n;) {
if(a[i] < b[j]) {
array[k] = a[i];
++i;
}
else {
array[k] = b[j];
++j;
}
++k;
}
while(i<n) {
array[k] = a[i];
++i;
++k;
}
while(j<m) {
array[k] = b[j];
++j;
++k;
}
for (int i = 0; i < n+m; ++i) {
cout<<array[i];
}
cout<<endl;
Я думал о том, чтобы пересечь его назад и выбрать самого большого персонажа и начал добавлять его сзади. С ограниченным тестом, который я выполнял, это выглядело хорошо.
int n = a.size(), m = b.size();
int i =n-1, j=m-1, k=n+m-1; char array[n+m];
for(; i>=0 && j>=0;) {
if(a[i] > b[j]) {
array[k] = a[i];
--i;
}
else {
array[k] = b[j];
--j;
}
--k;
}
while(i>=0) {
array[k] = a[i];
--i;
--k;
}
while(j>=0) {
array[k] = b[j];
--j;
--k;
}
for (int i = 0; i < n + m; ++i) {
cout<<array[i];
}
cout<<endl;
Но я не уверен, что всегда будет всегда предлагать оптимальное решение.
Является ли это решение правильным в первую очередь, и если да, то кто-то может дать мне небольшое доказательство того, почему это также создает оптимальное решение.
У меня есть ощущение, что ваш жадный алгоритм почти правильно, и он должен начать работать, если вы раскошелиться поиска, когда вы видите одинаковые буквы в обеих строках. – Manvel