最小操作次数问题

这种类型的题目关键是如何由当前状态推出下一状态,所有的状态都存在一个队列中,先进先出,遍历搜有的状态直到出现目标状态!

典型例题: H854

参考题解如下:
关键就是如何求下一状态,以及要使用一个集合记录曾经出现过的状态防止重复出现浪费时间

class Solution:
    def kSimilarity(self, s1: str, s2: str) -> int:
        n = len(s1)
        #  q中存储的是每k步操作下的不同的状态
        q = deque([s1])

        #  传入这一个状态返回所有可能的下一状态
        def next_statue(s):
            i = 0
            while i < n and s[i] == s2[i]:
                i += 1
            res = []
            for j in range(i + 1, n):
                #  s[j]!=s2[j]是因为s的最终状态下第j位必须是s2[j]
                #      如果你这里换了后面肯定还要换回来,这不是徒增操作吗!
                if s[j] == s2[i] and s[j] != s2[j]:
                    res.append(s[:i] + s[j] + s[i + 1:j] + s[i] + s[j + 1:])
            return res

        ans = 0
        #  使用字典记录所有已经出现过的状态,当此状态再次出现时不进队列!
        #     如果操作一通之后回到了曾经出现过的的状态说明同样的操作步数下一定有更优的解法!
        has_appeared = {s1}
        while True:
            al_next = deque([])
            while q:
                cur_status = q.popleft()
                if cur_status == s2: return ans
                for cur_next in next_statue(cur_status):
                    if cur_next not in has_appeared:
                        has_appeared.add(cur_next)
                        al_next.append(cur_next)
            q = al_next
            ans += 1

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值