此题解采用了深度优先搜索(DFS)的方法来求解字符串s1通过最少次数的交换变为字符串s2的问题。首先,它通过一个循环去除掉s1和s2中相同位置上相同的字符,只保留不同的字符,从而减少了问题的规模。然后,定义一个递归函数dfs来尝试所有可能的字符交换,通过递归搜索找到最小的交换次数。递归过程中使用了剪枝来减少不必要的计算,例如,如果当前已有的交换次数已经超过了已知的最小交换次数,就停止进一步搜索。此外,还计算了当前不匹配的字符对至少需要的交换次数来进行更深入的剪枝。
时间复杂度: O(n!)
空间复杂度: O(n)
class Solution:
def kSimilarity(self, s1: str, s2: str) -> int:
s, t = [], []
for x, y in zip(s1, s2):
if x != y: # 收集所有不同的字符对
s.append(x)
t.append(y)
n = len(s)
if n == 0: # 如果没有不同的字符,直接返回0
return 0
ans = n - 1 # 初始化最小交换次数为n-1
def dfs(i, cost):
nonlocal ans # 引用外部变量ans
if cost > ans: # 如果当前成本已经超过已知最小值,则剪枝
return
while i < n and s[i] == t[i]: # 跳过已经匹配的位置
i += 1
if i == n: # 如果所有位置都匹配了
ans = min(ans, cost)
return
diff = sum(s[j] != t[j] for j in range(i, len(s))) # 计算剩余不匹配的数量
min_swap = (diff + 1) // 2 # 估算至少还需要的交换次数
if cost + min_swap >= ans: # 使用估算值进行剪枝
return
for j in range(i + 1, n):
if s[j] == t[i]: # 查找可以与s[i]交换的字符s[j]
s[i], s[j] = s[j], s[i] # 执行交换
dfs(i + 1, cost + 1) # 递归搜索下一步
s[i], s[j] = s[j], s[i] # 撤销交换
dfs(0, 0) # 从第0位开始搜索
return ans # 返回最小交换次数