交换字符使得字符串相同[贪心]

前言

贪心算法,必须先看清楚有哪些选择,才能在这些选择的基础上进行贪心,做最优选择,除此之外,还得看局部最优会不会形成全局最优,否则无法贪心。

一、交换字符使得字符串相同

在这里插入图片描述

二、贪心

1、分析问题的思路过程

有两个问题很重要,
1.如何交换才能使两字符串相同,有哪些交换方式?
2.要想交换次数最少,选择何种方式能快点交换?
问题1)相同的字符肯定不用动,不同的字符对上下交换是无意义的,这能进行两个不同对的交叉交换。
问题2)
当两对字符对相同性质时,如y-x | y - x,一次交叉交换就能让2对字符相同,这是贪心点,是最优选择。
当两对字符对不同性质时,如y - x | x - y,一次交叉交换是不行的,得先做一次无意义的上下交换,转换成相同性质对y - x | y - x,再做一次交叉换,一共两次,这必定是次优选择。

2、go

func minimumSwap(s1 string, s2 string) int {
    x,y := 0,0
    for i := 0;i < len(s1);i++ {
        if s1[i] != s2[i] {
            if s1[i] == 'x' {
                x++
            }
            if s1[i] == 'y' {
                y++
            }
        }
    }
    // 要么两个都剩下x/y,要么都不剩,否则出现单对x/y,则无法交换成功。
    if x & 1 != y & 1 {
        return -1
    }
    return (x + 1) >> 1 + (y + 1) >> 1
}
// 寻找最小交换次数
// 当x/y的数量为奇数时,一定无法交换成功。
// 抽象,我们思考中有这个交换过程,但是结果只要交换次数,不需要具体交换过程。
// xxyy yyxx
// 不仅要理解如何交换,还得理解怎么交换更快是两字符串相同?
// x x y y x y x y x x
// x y y x y x x x y x
// 不位置不同的字符提取出来
// x y x y y x
// y x y x x y
// 上下不同,上下交换也还是不同,只能对角线交换,当不同的字符是一对时(y / x,y / x),对角线交换xy即可。
// 记录不同的x/y个数,return (x + 1) >> 1 + (y + 1) >> 1
// 经过上述分析,问题就转换成记录x/y的个数,然后各子折半取上整的总和,按照贪心的做法,一次交换尽量解决两对同性质的x/y对,最后剩下的就需要交换两次,所以取上整。

总结

1)思考问题,得有一个分析的过程,最好写下来,有助于后面的逐步分析。
2)对于贪心问题,首先得知道选择有哪些,否则无从贪起,就像这里,必须知道如何交换字符串才能得到相同字符串,知道其中的交换方式有两种,才能贪心的交换。

参考资料

[1] LeetCode 交换字符使得字符串相同

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值