854. 相似度为 K 的字符串

如果可以通过将 A 中的两个小写字母精确地交换位置 K 次得到与 B 相等的字符串,我们称字符串 A 和 B 的相似度为 KK 为非负整数)。

给定两个字母异位词 A 和 B ,返回 A 和 B 的相似度 K 的最小值。

 

示例 1:

输入:A = "ab", B = "ba"
输出:1

示例 2:

输入:A = "abc", B = "bca"
输出:2

示例 3:

输入:A = "abac", B = "baca"
输出:2

示例 4:

输入:A = "aabc", B = "abca"
输出:2

 

提示:

  1. 1 <= A.length == B.length <= 20
  2. A 和 B 只含有集合 {'a', 'b', 'c', 'd', 'e'} 中的小写字母。

之前写的那种BFS会TLE,预先prune也TLE,就是开始把22交换可以都match的先交换掉

class Solution:
    def kSimilarity(self,A,B):
        """
        :type A: str
        :type B: str
        :rtype: int
        """
        a,b=A,B
        if a==b: return 0
        vis=set()
        step=0
        q,qq=[a],[]
        while q:
            while q:
                t=q.pop()
                for i in range(len(t)):
                    if t[i]==b[i]: continue
                    for j in range(i+1, len(b)):
                        if t[j]==b[j]: continue
                        if t[i]==b[j] or t[j]==b[i]:
                            tt=t[0:i]+t[j]+t[i+1:j]+t[i]+t[j+1:]
                            if tt in vis: continue
                            vis.add(tt)
                            qq.append(tt)
                            if tt==b: return step+1
            q,qq=qq,q
            step+=1

想想,上面的BFS就是没有顺序的搜索,而更有效的方式是一位一位的来针对性的有目的的搜索,这样本身会prune掉很多(举一些例子就可以明白),如果自己手动来做的话,应该也是这么一个思路

class Solution:
    def kSimilarity(self,A,B):
        """
        :type A: str
        :type B: str
        :rtype: int
        """
        a,b=A,B
        if a==b: return 0
        vis={}
        q,qq=[(a,0)],[]
        vis[a]=0
        
        for idx in range(len(a)):
            while q:
                t,step=q.pop()
                if t[idx]==b[idx]:
                    qq.append((t,step))
                else:
                    for i in range(idx+1, len(a)):
                        if t[i]==b[idx]:
                            tt=t[0:idx]+t[i]+t[idx+1:i]+t[idx]+t[i+1:]
                            if tt in vis and vis[tt]<=step+1: continue
                            vis[tt] = step+1
                            qq.append((tt,step+1))
            q,qq=qq,q
        
        res = 9999999
        for t,step in q:
            if t==b: res=min(res,step)
        return res



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值