Minimum Swaps to Make Strings Equal
Problem: Given two strings consisting of characters ‘x’ and ‘y’, you can swap any two letters that belong to different strings. Find and return the minimum number of swaps necessary to make two strings equal. If it is not possible to make strings equal, return -1.
Constraints:
- The length of a string is between 1 and 100
- The length of two strings is the same.
- The strings only contain the letters ‘x’ and ‘y’.
Table of contents
Initial thought process
Let us start by making some observations. To being with, it is not actually required to swap the letters. We simply need to count the number of swaps necessary to make the string equal. Therefore, a possible strategy is to walk the strings, and count the number of swaps necessary by following some general rules. The key to the solution, then, is to find those rules. Considering some simplified cases will help us arrive at some general rules.
(Case 1) Impossible
index | 0 | 1 |
---|---|---|
s1 | x | y |
s2 | x | x |
Let us consider ‘xy’ and ‘xx’. No matter how many swaps we make, it is not possible to make those strings equal.
(Case 2) One swap
index | 0 | 1 |
---|---|---|
s1 | x | x |
s2 | y | y |
Let us consider ‘yy’ and ‘xx’. We can make the strings equal by swapping s1[0]
and s2[1]
.
(Case 3) Two swaps
index | 0 | 1 |
---|---|---|
s1 | x | y |
s2 | y | x |
Let us consider ‘xy’ and ‘yx’. We can make the strings equal with two swaps. One way is to swap s1[0]
and s2[0]
, and then swap s1[0]
and s2[1]
.
Rules
If we find a mismatch where s1
has x and s2
has y, there are two strategies to resolve the mismatch.
- Find another mismatch where
s1
has x ands2
has y. We can resolve those mismatches with one exchange. - Find another mismatch where
s1
has y ands2
has x. We can resolve those mismatches with two exchanges.
Why?
- An example of the first strategy is a situation:
s1
= xx and s2 = yy (case 2). We swaps1[0]
withs2[1]
to make both strings equal to yx. - An example of the second strategy is a situation
s1
= xy and s2 = yx (case 3). We swaps1[0]
withs2[0]
, thens1[0]
withs2[1]
to make both strings equal to xy.
Solution
With these two rules in mind, let us count the number of two different mismatches: (1) a mismatch where s1
has x, and (2) a mismatch where s1
has y. Then, we can try to resolve the mismatches by applying the first rule, then the second rule if necessary. If a mismatch remains at the end, we know that it is impossible to make the strings equal (case 1). The order of exchange is not important. Therefore we can simply count and use the counts to resolve the mismatches.
With this in mind, we arrive at the following solution.
|
|
While this question clarifies that you should return -1
in case a solution does not exist, an interview question is often not always that specific on how to handle edge cases. You will probably be responsible for clarifying how to handle the situation in which no solution exists, or whether a solution always exists at all.
Complexity
We loop through the strings once. Therefore, the time complexity is O(N)
where N is the length of s1
and s2
. The space complexity is O(1)
because we use a constant amount of memory regardless of the input size.
Validation
The validation can be extended to verify the other contrasts of the inputs. We can clarify with the interviewer about how to handle invalid inputs. For example, we can throw an exception, or return -1, indicating no solution is possible. Furthermore, the question is often ambiguous about the constraints of the input. It is your responsibility to clarify them in an interview setting.
|
|
Note that validateString
does not change the complexity of the solution.
Follow-ups
Swap letters in the same string
How will the solution change, if we can swap letters belonging to the same string? In this situation, case 3 in our observation will take one, rather than two, swaps to resolve. Concretely, suppose ‘xy’ and ‘yx’. Then, we can simply swap s1[0] and s1[1] to make the strings equal. In effect, we are able to resolve any two mismatches with a single swap.
|
|
An additional letter ‘z’
How will we extend the solution if the strings can contain an additional letter, say, ‘z’? In this case, the underlying mechanics of the solution does not change. Rather, we we will need to be more specific about the kind of mismatches, and extend our rules. Specifically, we need to count 6 different kinds of mismatches:
- “xy mismatch” where
s1
has ‘x’ ands2
has ‘y’. - “xz mismatch” where
s1
has ‘x’ ands2
has ‘z’. - “yx mismatch” where
s1
has ‘y’ ands2
has ‘x’. - “yz mismatch” where
s1
has ‘y’ ands2
has ‘z’. - “zx mismatch” where
s1
has ‘z’ ands2
has ‘x’. - “zy mismatch” where
s1
has ‘z’ ands2
has ‘y’.
Then, our rules should be extended as follows:
For an “xy mismatch”,
- if there is another “xy mismatch”, we can resolve those mismatched with one exchange.
- if there is another “yx mismatch”, we can resolve those mismatched with two exchanges.
For an “xz mismatch”,
- if there is another “xz mismatch”, we can resolve those mismatched with one exchange.
- if there is another “zx mismatch”, we can resolve those mismatched with two exchanges.
And so on, for the rest of the mismatch types. Then, we simply apply those rules based on the count of the mismatches of each types.
|
|
The complexity of the solution does not change because we are still looping through the strings once, counting mismatches. Here, we observe the value of deriving general rules for the solution. To handle an additional character, we could simply extend the rules and update the solution accordingly.
Lessons learned
- When a question asks to find the number of operations, you don’t necessarily have to perform those operations. For instance, if we actually swapped the characters from the strings, the solution would be more complicated and have worse complexity.
- Derive general rules for the solution by examining simplified cases.
- When manipulating strings, it helps to draw a table and observe the behaviour as you iterate through them.