LeetCode:交换字符使得字符串相同
有两个长度相同的字符串 s1 和 s2,且它们其中 只含有 字符 "x" 和 "y",你需要通过「交换字符」的方式使这两个字符串相同。
每次「交换字符」的时候,你都可以在两个字符串中各选一个字符进行交换。
交换只能发生在两个不同的字符串之间,绝对不能发生在同一个字符串内部。也就是说,我们可以交换 s1[i] 和 s2[j],但不能交换 s1[i] 和 s1[j]。
最后,请你返回使 s1 和 s2 相同的最小交换次数,如果没有方法能够使得这两个字符串相同,则返回 -1 。
示例 1:
输入: s1 = "xx", s2 = "yy"
输出: 1
解释: 交换 s1[0] 和 s2[1],得到 s1 = "yx",s2 = "yx"。
示例 2:
输入: s1 = "xy", s2 = "yx"
输出: 2
解释: 交换 s1[0] 和 s2[0],得到 s1 = "yy",s2 = "xx" 。
交换 s1[0] 和 s2[1],得到 s1 = "xy",s2 = "xy" 。
注意,你不能交换 s1[0] 和 s1[1] 使得 s1 变成 "yx",因为我们只能交换属于两个不同字符串的字符。
示例 3:
输入: s1 = "xx", s2 = "xy"
输出: -1
提示:
1 <= s1.length, s2.length <= 1000s1.length == s2.lengths1, s2只包含'x'或'y'。
解题思路
题目描述中的示例1和示例2,分别代表两种交换的情况,即 xx 和 yy,以及 xy 和 yx。 示例1可以用一次交换实现不同位数减2,示例2需要用两次交换实现不同位数减2. 明显示例1效率更高,因此应该尽量用示例一的方式。 s1和s2中的字符,如果同一位置相等,不影响最后结果,可忽略。 不同的情况,如果s1[i]为x,s2[i]为y,是一种情况,我们可记为xy;另一种情况可记为yx。 当xy和yx都为偶数时,可以组成几个xxx和几个yyy的形式,这是既可以用示例一的方式了; 如果为奇数,可以先把偶数的部分使用示例一进行交换,再把剩下的部分用示例而进行交换。
求奇数、偶数和除以2的部分,都可以用位运算加速。
要求出最小的使得两个字符串都相等的交换次数,两个字符串中都只含有 x 和 y, 两个字符串中字符不同的可能情况只有 s1[i] = 'x' , s2[i] ='y' 或 s1[i] = 'y' , s2[i] ='x' 两种情况,
- 为了求得最小交换次数,优先将按示例一的情况,凑出连续不同的情况
- 针对两种情况计数模2后的结果
- 判断是否能够使得两个字符串通过交换获得相同字符顺序,进一步补齐示例二的情况
解题代码
public int minimumSwap(String s1, String s2) {
int xy = 0, yx = 0;
int n = s1.length();
for (int i = 0; i < n; i++) {
if (s1.charAt(i) == 'x' && s2.charAt(i) == 'y')
xy++;
else if (s1.charAt(i) == 'y' && s2.charAt(i) == 'x')
yx++;
}
if (((xy + yx) & 1) == 1) return -1;
return (xy >> 1) + (yx >> 1) + (xy & 1) + (yx & 1);
}
运行结果
复杂度详情
- 空间复杂度:
- 时间复杂度:
在掘金(JUEJIN)一起进步,一起成长!