如果可以通过将 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
提示:
1 <= A.length == B.length <= 20
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