1247. 交换字符使得字符串相同

1247. 交换字符使得字符串相同

难度中等162收藏分享切换为英文接收动态反馈

有两个长度相同的字符串 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

示例 4:

输入:s1 = "xxyyxyxyxx", s2 = "xyyxyxxxyx"
输出:4

提示:

  • 1 <= s1.length, s2.length <= 1000
  • s1, s2 只包含 'x' 或 'y'

思路:首先需要明确的一点是,如果对于索引idx,s1[idx]==s2[idx]的情况下,我们是不用动的,这样才符合我们需要的最小交换次数的要求。现在我们来看看在s1[idx]与s2[idx]不相同的情况:

A. s1[idx]=='x',s2[idx]=='y',此种情况记为xy

        如上图所示,在这种情况下,可以交换s1[idx_1]与s2[idx_2]或者交换s1[idx_2]与s2[idx_1],即将两个xy进行一次置换可以消去两个xy模式。

B. s1[idx]=='y',s2[idx]=='x',此种情况记为yx

       与上类似,这种情况可以将两个yx进行一次置换可以消去两个yx模式。

以上讨论限于都为偶数的情况,那么对于奇数情况呢?

首先必须明确的是,如果xy和yx模式的个数一个为奇数一个为偶数就不可能通过交换将两者变成相同字符串。举例来说,一个xy模式,要么使用另一个xy模式与之采用一步交换消去,要么使用yx模式与之采用两步交换消去,如果只有一个xy模式,是没有办法消去的。

xy模式与yx模式的两步消除法在题目中已经给出了例子:

输入: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",因为我们只能交换属于两个不同字符串的字符。

因此我们已经有了算法流程:

        1.统计xy、yx模式的出现次数

        2.如果xy模式和yx模式的和为奇数,势必为一个奇数一个偶数,此时一定没有办法成功交换,返回-1

        3.如果二者都为偶数,那么需要的最小交换次数为xy_num / 2 + yx_num / 2

        4.如果为两个奇数,那么需要的最小交换次数为xy_num / 2 + yx_num / 2 + 2

class Solution {
public:
    int minimumSwap(string s1, string s2) {
        if(s1.length() != s2.length()) return -1;
        int xy_num = 0, yx_num = 0, idx;
        for(idx = s1.length() - 1; idx >= 0; -- idx){
            if(s1[idx] == 'x' && s2[idx] == 'y'){
                ++ xy_num;
            }else if(s1[idx] == 'y' && s2[idx] == 'x'){
                ++ yx_num;
            }
        }
        if((xy_num + yx_num) & 1){
            return -1;
        }//必然是两个偶数或者两个奇数 如果是两个偶数则只需要各自和各自交换 如果是两个奇数 则最后+2
        return xy_num / 2 + yx_num / 2 + (xy_num & 1 ? 2 : 0);
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值