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;
}