这是在线编码挑战之一(已完成)提出的问题<我只是需要一些逻辑来说明如何接近。
我们有两个字符串A和B,具有相同的超字符集。我们需要改变这些字符串来获得两个相等的字符串。在每个步骤中,我们可以执行以下操作之一:
1. swap two consecutive characters of a string
2. swap the first and the last characters of a string
移动可以在任一字符串上执行。
为了获得两个相等的字符串,我们需要的最小移动次数是多少?
输入格式和约束:
输入的第一行和第二行包含两个字符串A和B。保证它们的超集字符相等。
1 <= length(A) = length(B) <= 2000
All the input characters are between 'a' and 'z'
输出格式:
将最小移动次数打印到输出的唯一行
Sample input:
aab
baa
Sample output:
1
说明:
交换字符串aab的第一个和最后一个字符以将其转换为baa。这两个字符串现在相等。
编辑:这是我的第一次尝试,但我得到了错误的输出。有人能指导我我的方法有什么问题吗?
int minStringMoves(char* a, char* b) {
int length, pos, i, j, moves=0;
char *ptr;
length = strlen(a);
for(i=0;i<length;i++) {
// Find the first occurrence of b[i] in a
ptr = strchr(a,b[i]);
pos = ptr - a;
// If its the last element, swap with the first
if(i==0 && pos == length-1) {
swap(&a[0], &a[length-1]);
moves++;
}
// Else swap from current index till pos
else {
for(j=pos;j>i;j--) {
swap(&a[j],&a[j-1]);
moves++;
}
}
// If equal, break
if(strcmp(a,b) == 0)
break;
}
return moves;
}
可以使用动态编程。在存储所有中间结果的同时,检查所有交换可能性,以及花费您最少的步骤。实际上,您将计算每个可能的目标字符串的最小步数,这些目标字符串可以通过应用给定的规则多次获得。一旦计算完所有步骤,就可以打印到达目标字符串所需的最小步数。以下是JavaScript中的示例代码,以及它在“aab”和“baa”示例中的用法:
function swap(str, i, j) {
var s = str.split("");
s[i] = str[j];
s[j] = str[i];
return s.join("");
}
function calcMinimumSteps(current, stepsCount)
{
if (typeof(memory[current]) !== "undefined") {
if (memory[current] > stepsCount) {
memory[current] = stepsCount;
} else if (memory[current] < stepsCount) {
stepsCount = memory[current];
}
} else {
memory[current] = stepsCount;
calcMinimumSteps(swap(current, 0, current.length-1), stepsCount+1);
for (var i = 0; i < current.length - 1; ++i) {
calcMinimumSteps(swap(current, i, i + 1), stepsCount+1);
}
}
}
var memory = {};
calcMinimumSteps("aab", 0);
alert("Minimum steps count: " + memory["baa"]);
A*算法可能适用于此问题。
初始节点将是原始字符串
目标节点将是目标字符串
节点的每个子节点都将是该字符串的所有可能转换
当前成本g(x)
只是迄今为止的转换次数
启发式h(x)
是错误位置字符数的一半。
由于h(x)
是允许的(因为单个转换不能在其正确位置放置超过2个字符),因此目标字符串的路径将提供尽可能少的转换次数。
然而,初级实现可能会太慢。计算字符串的所有可能转换将是相当昂贵的。
请注意,节点的兄弟姐妹(父节点的子节点)与其子节点之间有很多相似之处。因此,您可以计算原始字符串的所有转换,并从那里简单地复制和重新计算涉及更改字符的数据。
看看这个例子:
aaaaaaaaab
abaaaaaaaa
您的解决方案:8
aaaaaaaaab -> aaaaaaaaba -> aaaaaaabaa -> aaaaaabaaa -> aaaaabaaaa ->
aaaabaaaaa -> aaabaaaaaa -> aabaaaaaaa -> abaaaaaaaa
正确的解决方案:2
aaaaaaaaab -> baaaaaaaaa -> abaaaaaaaa
您应该检查在另一个方向上交换是否会提供更好的结果。
但有时你也会破坏字符串的前一部分。如:
caaaaaaaab
cbaaaaaaaa
caaaaaaaab -> baaaaaaaac -> abaaaaaaac
您需要在这里进行另一次交换,以将“c”放回第一位。
正确的算法可能更复杂,但现在您可以看到解决方案中的错误。
问题内容: 通过搜索发现了类似的问题,但我是一位新的(糟糕的)程序员,无法理解答案。 我有一个.txt文件,其中包含多个字符串,以’-‘分隔。我使用拆分将一些字符串分成变量,其中两个相等,但是在if语句中它们不相等。 这将产生以下结果: 瑞典 瑞典 没有 在两个“ Sweden”字符串之前和之后都有一个空格,并且它们都用大写字母“ S”编写,但不相等吗?我在哪里搞砸了? 问题答案: 最后一个元素包
当且仅当“字符串中的所有不同字符重复相同次数”时,称字符串为良好字符串。 现在,给定一个长度为n的字符串,我们必须在这个字符串中进行的最小更改次数是多少,这样字符串就变得正常了。 注意:我们只允许使用小写英文字母,我们可以将任何字母更改为任何其他字母。 示例:让String为yyxzzxxx 那么这里的答案是2。 说明:一种可能的解决方案YYXYXX。我们已将2“z”更改为2“y”。现在“x”和“
您将得到一个有N个节点的有根树。每个节点包含一个小写英文字母。标签为%1的节点是根。有Q个问题的形式,X,S:这里X是子树的根,S是一个字符串。 输入格式: 第一行输入由两个空格分隔的整数N和Q组成,它们分别是树中的节点数和问题数。下一行将包含N个空格分隔的小写英文字母,其中第i个字母将是存储在带有标签i的节点中的字母。接下来的n-1行中的每一行都包含两个空格分隔的整数u和v,表示在接下来的Q行后
我正在学习最长公共子序列,使用以下算法: 公共级LCS{ 但是程序返回一个ErrorCharAt(未知来源),并且没有做任何事情。 另外,如果我将int i和j更改为0,那么下面的E将是索引-1和错误 我现在很迷路。有人能帮我吗?
给出了一个大小为n的数组,其中表示位置处的硬币数量。“移动”包括将一定数量的硬币从位置移动到位置或。重新分配硬币所需的最小移动次数是多少,这样每个位置上正好有一枚硬币?你被保证有相同数量的硬币与有的插槽,以分配他们。 例如,给定输入 输出为 null 解决这个问题的有效方法是什么?
问题内容: 这是我查询的结果,但顺序不正确。我想按最后2个字符排序。结果应为:下面。 我的查询: 第二:sqlfiddle 问题答案: 试试这个: 检查 SQL FIDDLE DEMO 输出