【问题标题】:Change strings to make them equal更改字符串以使它们相等
【发布时间】:2015-02-19 06:18:20
【问题描述】:

参考问题HERE

我们有两个字符串 A 和 B 具有相同的超级字符集。我们 需要更改这些字符串以获得两个相等的字符串。在每一个动作 我们可以执行以下操作之一:

1- 交换字符串的两个连续字符
2-交换第一个和 字符串的最后一个字符

可以对任一字符串执行移动。最小数量是多少 为了获得两个相等的字符串,我们需要多少步?输入 格式和约束:输入的第一行和第二行 包含两个字符串 A 和 B。保证它们的超集 字符相等。 1

看起来这必须使用动态编程来解决。但我无法提出方程式。有人在回答中提出了建议-但看起来不太好。

dp[i][j] = 
Min{ 
dp[i + 1][j - 1] + 1, if str1[i] = str2[j] && str1[j] = str2[i]
dp[i + 2][j] + 1, if str1[i] = str2[i + 1] && str1[i + 1] = str2[i]
dp[i][j - 2] + 1, if str1[j] = str2[j - 1] && str1[j - 1] = str2[j]
}
In short, it's 
dp[i][j] = Min(dp[i + 1][j - 1], dp[i + 2][j], dp[i][j - 2]) + 1.
Here dp[i][j] means the number of minimum swaps needs to swap str1[i, j] to str2[i, j]. Here str1[i, j] means the substring of str1 starting from pos i to pos j :)

Here is an example like the one in the quesition,
str1 = "aab",
str2 = "baa"

dp[1][1] = 0 since str1[1] == str2[1];
dp[0][2] = str1[0 + 1][2 - 1] + 1 since str1[0] = str2[2] && str1[2] = str2[0].

【问题讨论】:

  • 我认为至少在这个解决方案中不能使用 DP,因为你不能用中间一个元素来改变最后一个元素的位置

标签: string algorithm


【解决方案1】:

你有两个原子操作:

  1. 以成本 1 连续交换

  2. 以成本 1 交换第一个和最后一个

一个有趣的事实:

  1. 和 2. 如果字符串结尾将附加到字符串开头(圆形字符串),则相同

所以我们可以推导出一个更通用的操作

  1. 使用 cost = |from - to| 移动一个角色(跨境)

这个问题对我来说似乎不是二维的,或者我无法确定维度。将此算法视为幼稚的方法:

private static int transform(String from, String to) {
    int commonLength = to.length();
    List<Solution> worklist = new ArrayList<>();
    worklist.add(new Solution(0,from));
    while (!worklist.isEmpty()) {
        Solution item = worklist.remove(0);
        if (item.remainder.length() == 0) {
            return item.cost;
        } else {
            int toPosition = commonLength - item.remainder.length();
            char expected = to.charAt(toPosition);
            nextpos : for (int i = 0; i < item.remainder.length(); i++) {
                if (item.remainder.charAt(i) == expected) {
                    Solution nextSolution = item.moveCharToBegin(i, commonLength);
                    for (Solution solution : worklist) {
                        if (solution.remainder.equals(nextSolution.remainder)) {
                            solution.cost = Math.min(solution.cost, nextSolution.cost);
                            continue nextpos;
                        }
                    }
                    worklist.add(nextSolution);
                }
            }
        }
    }
    return Integer.MAX_VALUE;
}

private static class Solution {
    public int cost;
    public String remainder;

    public Solution(int cost, String remainder) {
        this.cost = cost;
        this.remainder = remainder;
    }

    public Solution moveCharToBegin(int i, int length) {
        int costOffset = Math.min(i, length - i); //minimum of forward and backward circular move
        String newRemainder = remainder.substring(0, i) + remainder.substring(i + 1);
        return new Solution(cost + costOffset, newRemainder);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-01
    • 1970-01-01
    • 2019-07-26
    • 2012-08-19
    • 1970-01-01
    • 1970-01-01
    • 2011-02-11
    • 2016-12-18
    相关资源
    最近更新 更多