题目
如果可以通过将 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