854. 相似度为 K 的字符串

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

给定两个字母异位词 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

输入: A="abccaacceecdeea";B="bcaacceeccdeaae" 
输出:  9

提示:

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

【困难】
【分析】

class Solution:
    def kSimilarity(self, A: str, B: str) -> int:
        def findChange(S):
            for i in range(len(S)):
                if S[i]!=B[i]:
                    break
            S_=list(S)
            for j in range(i+1,len(S)):
                if B[i]==S_[j]:
                    S_[j],S_[i]=S_[i],B[i]
                    yield( "".join(S_))
                    S_[j],S_[i]=S_[i],S_[j]        
             
        queue=[A]
        seen={A:0}
        while queue:
            A=queue.pop(0)
            if A==B:
                return(seen[A])
            for A_ in findChange(A):
                if A_ not in seen:
                    seen[A_]=seen[A]+1
                    queue.append(A_) 

在这里插入图片描述
注:本来是想用BFS来做的,但是里面我用 A A A的索引 i a i_a ia代入了循环,所以导致结果不对,所以改成了把所有的都循环一遍最后再输出交换次数最少的那个值,但是这样就变成了暴力遍历,结果是对的,时间却超限了,此代码见下面。
改进:i_a不要引入循环,再写一个函数来找 A A A从左到右第一个不等于B的索引(见上面def findChange)。

class Solution:
    def kSimilarity(self, A: str, B: str) -> int:
        queue=[(A,0,0)]
        res=float("inf")
        i_a=0
        while queue and i_a<len(A)-1:
            A,step,i_a=queue.pop(0)
            if A==B:
                if step<res:
                    res=step
            if A[i_a]!=B[i_a]:
                index=[]
                for j in range(i_a+1,len(A)):
                    if A[j]==B[i_a]:
                        index.append(j)
                for i_b in index:
                    A_=list(A)
                    A_[i_b]=A_[i_a]
                    A_[i_a]=B[i_a]
                    queue.append((''.join(A_),step+1,i_a+1))                    
            else:
                queue.append((A,step,i_a+1))
        return res 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值