Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change strings to make them equal

Referring to question HERE

We have two strings A and B with the same super set of characters. We need to change these strings to obtain two equal strings. In each move we can perform one of the following operations:

1- swap two consecutive characters of a string
2- swap the first and the last characters of a string

A move can be performed on either string. What is the minimum number of moves that we need in order to obtain two equal strings? Input Format and Constraints: The first and the second line of the input contains two strings A and B. It is guaranteed that the superset their characters are equal. 1 <= length(A) = length(B) <= 2000 All the input characters are between 'a' and 'z'

It looks like this will have to solved using dynamic programming. But I am not able to come up with equations. Some one has suggested them in answer - but it does not look all right.

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].
like image 904
Andy897 Avatar asked Feb 19 '15 06:02

Andy897


People also ask

How do you make a string equal?

Below is the illustration of the steps: Initialize the parent of each alphabet to itself. Traverse the two strings simultaneously with the help of index and check if the corresponding characters have different parents then merge the string which has less rank in the strings.

How do you make all characters in a string equal?

Input: words = ["abc","aabc","bc"] Output: true Explanation: Move the first 'a' in words[1] to the front of words[2], to make words[1] = "abc" and words[2] = "abc". All the strings are now equal to "abc", so return true .

How do you make two strings equal in Java?

Java String equals() MethodThe equals() method compares two strings, and returns true if the strings are equal, and false if not. Tip: Use the compareTo() method to compare two strings lexicographically.

What is K anagram?

EasyAccuracy: 26.28%Submissions: 39073Points: 2. Given two strings of lowercase alphabets and a value K, your task is to complete the given function which tells if two strings are K-anagrams of each other or not. Two strings are called K-anagrams if both of the below conditions are true.


1 Answers

You have two atomic operations:

  1. swap consecutive with cost 1

  2. swap first and last with cost 1

One interesting fact:

  1. and 2. are the same if the strings end would be attached to the strings begin (circular string)

So we can derive a more generic operation

  1. move a character with cost = |from - to| (across borders)

The problem rather seems not 2-dimensional to me, or yet I cannot determine the dimensions. Take this algorithm as naive approach:

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);
    }
}
like image 170
CoronA Avatar answered Sep 20 '22 16:09

CoronA