Overflow in intermediate arithmetic
Wrong move: Temporary multiplications exceed integer bounds.
Usually fails on: Large inputs wrap around unexpectedly.
Fix: Use wider types, modular arithmetic, or rearranged operations.
Move from brute-force thinking to an efficient approach using math strategy.
You are given two strings s1 and s2 of equal length consisting of letters "x" and "y" only. Your task is to make these two strings equal to each other. You can swap any two characters that belong to different strings, which means: swap s1[i] and s2[j].
Return the minimum number of swaps required to make s1 and s2 equal, or return -1 if it is impossible to do so.
Example 1:
Input: s1 = "xx", s2 = "yy" Output: 1 Explanation: Swap s1[0] and s2[1], s1 = "yx", s2 = "yx".
Example 2:
Input: s1 = "xy", s2 = "yx" Output: 2 Explanation: Swap s1[0] and s2[0], s1 = "yy", s2 = "xx". Swap s1[0] and s2[1], s1 = "xy", s2 = "xy". Note that you cannot swap s1[0] and s1[1] to make s1 equal to "yx", cause we can only swap chars in different strings.
Example 3:
Input: s1 = "xx", s2 = "xy" Output: -1
Constraints:
1 <= s1.length, s2.length <= 1000s1.length == s2.lengths1, s2 only contain 'x' or 'y'.Problem summary: You are given two strings s1 and s2 of equal length consisting of letters "x" and "y" only. Your task is to make these two strings equal to each other. You can swap any two characters that belong to different strings, which means: swap s1[i] and s2[j]. Return the minimum number of swaps required to make s1 and s2 equal, or return -1 if it is impossible to do so.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: Math · Greedy
"xx" "yy"
"xy" "yx"
"xx" "xy"
determine-if-two-strings-are-close)make-number-of-distinct-characters-equal)Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #1247: Minimum Swaps to Make Strings Equal
class Solution {
public int minimumSwap(String s1, String s2) {
int xy = 0, yx = 0;
for (int i = 0; i < s1.length(); ++i) {
char a = s1.charAt(i), b = s2.charAt(i);
if (a < b) {
++xy;
}
if (a > b) {
++yx;
}
}
if ((xy + yx) % 2 == 1) {
return -1;
}
return xy / 2 + yx / 2 + xy % 2 + yx % 2;
}
}
// Accepted solution for LeetCode #1247: Minimum Swaps to Make Strings Equal
func minimumSwap(s1 string, s2 string) int {
xy, yx := 0, 0
for i := range s1 {
if s1[i] < s2[i] {
xy++
}
if s1[i] > s2[i] {
yx++
}
}
if (xy+yx)%2 == 1 {
return -1
}
return xy/2 + yx/2 + xy%2 + yx%2
}
# Accepted solution for LeetCode #1247: Minimum Swaps to Make Strings Equal
class Solution:
def minimumSwap(self, s1: str, s2: str) -> int:
xy = yx = 0
for a, b in zip(s1, s2):
xy += a < b
yx += a > b
if (xy + yx) % 2:
return -1
return xy // 2 + yx // 2 + xy % 2 + yx % 2
// Accepted solution for LeetCode #1247: Minimum Swaps to Make Strings Equal
struct Solution;
impl Solution {
fn minimum_swap(s1: String, s2: String) -> i32 {
let n = s1.len();
let s1: Vec<char> = s1.chars().collect();
let s2: Vec<char> = s2.chars().collect();
let mut x = 0;
let mut y = 0;
for i in 0..n {
if s1[i] == 'x' && s2[i] == 'y' {
x += 1;
}
if s1[i] == 'y' && s2[i] == 'x' {
y += 1;
}
}
if (x + y) % 2 != 0 {
return -1;
}
x / 2 + y / 2 + x % 2 * 2
}
}
#[test]
fn test() {
let s1 = "xx".to_string();
let s2 = "yy".to_string();
let res = 1;
assert_eq!(Solution::minimum_swap(s1, s2), res);
let s1 = "xy".to_string();
let s2 = "yx".to_string();
let res = 2;
assert_eq!(Solution::minimum_swap(s1, s2), res);
let s1 = "xx".to_string();
let s2 = "xy".to_string();
let res = -1;
assert_eq!(Solution::minimum_swap(s1, s2), res);
let s1 = "xxyyxyxyxx".to_string();
let s2 = "xyyxyxxxyx".to_string();
let res = 4;
assert_eq!(Solution::minimum_swap(s1, s2), res);
}
// Accepted solution for LeetCode #1247: Minimum Swaps to Make Strings Equal
function minimumSwap(s1: string, s2: string): number {
let xy = 0,
yx = 0;
for (let i = 0; i < s1.length; ++i) {
const a = s1[i],
b = s2[i];
xy += a < b ? 1 : 0;
yx += a > b ? 1 : 0;
}
if ((xy + yx) % 2 !== 0) {
return -1;
}
return Math.floor(xy / 2) + Math.floor(yx / 2) + (xy % 2) + (yx % 2);
}
Use this to step through a reusable interview workflow for this problem.
Try every possible combination of choices. With n items each having two states (include/exclude), the search space is 2ⁿ. Evaluating each combination takes O(n), giving O(n × 2ⁿ). The recursion stack or subset storage uses O(n) space.
Greedy algorithms typically sort the input (O(n log n)) then make a single pass (O(n)). The sort dominates. If the input is already sorted or the greedy choice can be computed without sorting, time drops to O(n). Proving greedy correctness (exchange argument) is harder than the implementation.
Review these before coding to avoid predictable interview regressions.
Wrong move: Temporary multiplications exceed integer bounds.
Usually fails on: Large inputs wrap around unexpectedly.
Fix: Use wider types, modular arithmetic, or rearranged operations.
Wrong move: Locally optimal choices may fail globally.
Usually fails on: Counterexamples appear on crafted input orderings.
Fix: Verify with exchange argument or monotonic objective before committing.