1247. Minimum Swaps to Make Strings Equal
给出两个只包含x
和 y
的字符串,问最少多少步交换可以让两个字符串相同?
交换是指任意s1[i]
和s2[j]
的一次交换。如果不能达到相同,输出-1,如果能输出最少交换次数。
Input1: s1 = “xx”, s2 = “yy”
Output1: 1
Input: s1 = “xy”, s2 = “yx”
Output: 2
Input: s1 = “xx”, s2 = “xy”
Output: -1
Input: s1 = “xxyyxyxyxx”, s2 = “xyyxyxxxyx”
Output: 4
题目的例子1和例子2贵的特别好,可以直接看出规律:
- 对应位置相同的话, 这个位置就直接跳过了,因为不需要变,只需要考虑不同的情况,也就是
xy
或者yx
; - 如果存在s1中有
xx
,s2中有yy
,那么直接交换一次就可以让这两个不同的位置都变成相同的,yy
和xx
同理,这样一步解决两个位置; - 如果还剩s1中有
xy
,s2中有yx
,那么只能交换两次来达到让这两个位置相同,如例子2。
所以优先消除xxyy
和yyxx
,最后解决xyyx
的情况。用变量xy
记录有多少对xy
,用变量yx
来记录有多少对yx
,由于两种情况都是两个两个消除的,所以最后两种肯定最多剩一个,也就是如果能达到完全相同,消除后的结果一定是以下两种之一:
xy
= 0 &&yx
= 0xy
= 1 &&yx
= 1
也就是说这两个一开始一定同号,要不都是奇数,要不都是偶数,那么yx + xy
一定就是偶数,如果不是,一定不能交换到相同的情况;如果最后各剩一个,那么交换步数需要加2,最后用个小技巧,直接计算出结果。
int minimumSwap(string s1, string s2) {
if(s1.length() != s2.length()) return -1;
int xy = 0, yx = 0;
for(int i = 0; i < s1.length(); ++i) {
if(s1[i] == s2[i]) continue;
if(s1[i] == 'x') ++xy;
else ++yx;
}
if((xy + yx) & 1) return -1; // 如果共奇数个,肯定不行
return (xy + 1) / 2 + (yx + 1) / 2;
}