1. 问题描述
(LeetCode 1247. 交换字符使得字符串相同)[https://leetcode-cn.com/problems/minimum-swaps-to-make-strings-equal/]
2. 问题分类
- 贪心算法
3. 问题解析
3.1 寻找规律
要求交换次数尽量少,基本思想:
- 若
s1[i]==s2[i]
(相同位置的s1和s2的字符相同),则continue
; - 若
s1[i]!=s2[i]
(相同位置的s1和s2的字符不相同),此处分为两种情况:- a)
s1="xx"; s2="yy"
,仅需要swap(s1[0], s2[1])
一次操作就可以完成 - b)
s1="xy"; s2="yx"
,需要swap(s1[0], s2[0]); swap(s1[0], s2[1])
两次操作完成
- a)
综上所述:
- 相同位置字符不同的总数必须为偶数,否则
return -1;
- 优先进行a)类的操作,剩余进行b)类操作
3.2 思想实现
- 统计
s1[i]==x
的个数为xy
,统计s1[i]==y
的个数为yx
- 若
(xy+yx)&1==1
,说明是奇数,则return -1;
- 所以
xy+yx
一定是偶数- 若
xy&1==0 && yx&1==0
,都是偶数,表示都是a)类,则总数为\(\frac{xy+yx}{2}\) - 若
xy&1==1 && yx&1==1
,都是奇数,表示有一个为b)类其他a)类,则总数为\(\frac{xy-1}{2}+\frac{yx-1}{2}+2=\frac{xy+yx}{2}+1\) - 以上两种情况都可以表示为\(\frac{xy+1}{2}+\frac{yx+1}{2}\)
- 若
4. 代码实现
class Solution {
public:
int minimumSwap(string s1, string s2) {
int xy=0,yx=0;
for(int i=0;i<s1.length();i++)
{
if(s1[i]==s2[i]) continue;
else if(s1[i]=='x') xy++;
else yx++;
}
return ((xy+yx)&1)==1?-1:(xy+1)/2+(yx+1)/2;
}
};