相似度为 K 的字符串
难度:
标签:
题目描述
代码结果
运行时间: 47 ms, 内存: 16.1 MB
/*
* Problem: Given two anagrams s1 and s2, return the minimum number of swaps required to make s1 equal to s2.
* Solution: This solution also uses BFS but utilizes Java Streams for some operations.
*/
import java.util.*;
import java.util.stream.Collectors;
public class SolutionStream {
public int kSimilarity(String s1, String s2) {
if (s1.equals(s2)) return 0;
int n = s1.length();
Queue<State> queue = new LinkedList<>();
Set<String> visited = new HashSet<>();
queue.add(new State(s1, 0));
visited.add(s1);
while (!queue.isEmpty()) {
State current = queue.poll();
List<Integer> mismatches = current.str.chars()
.filter(c -> c != s2.charAt(current.str.indexOf((char)c)))
.boxed()
.collect(Collectors.toList());
int i = mismatches.isEmpty() ? -1 : mismatches.get(0);
if (i == -1) continue;
for (int j = i + 1; j < n; j++) {
if (current.str.charAt(j) == s2.charAt(j) || current.str.charAt(j) != s2.charAt(i)) continue;
String next = swap(current.str, i, j);
if (next.equals(s2)) return current.k + 1;
if (visited.add(next)) {
queue.add(new State(next, current.k + 1));
}
}
}
return -1;
}
private String swap(String s, int i, int j) {
char[] arr = s.toCharArray();
char temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
return new String(arr);
}
private static class State {
String str;
int k;
State(String s, int k) {
this.str = s;
this.k = k;
}
}
}
解释
方法:
此题解采用了深度优先搜索(DFS)的方法来求解字符串s1通过最少次数的交换变为字符串s2的问题。首先,它通过一个循环去除掉s1和s2中相同位置上相同的字符,只保留不同的字符,从而减少了问题的规模。然后,定义一个递归函数dfs来尝试所有可能的字符交换,通过递归搜索找到最小的交换次数。递归过程中使用了剪枝来减少不必要的计算,例如,如果当前已有的交换次数已经超过了已知的最小交换次数,就停止进一步搜索。此外,还计算了当前不匹配的字符对至少需要的交换次数来进行更深入的剪枝。
时间复杂度:
O(n!)
空间复杂度:
O(n)
代码细节讲解
🦆
在递归函数`dfs`中,为什么可以直接返回0当`n == 0`,即没有不同的字符?是否意味着s1和s2完全相同?
▷🦆
在寻找可以与`s[i]`交换的字符`s[j]`时,为什么仅考虑`s[j] == t[i]`的情况?是否存在其他可能的有效交换条件?
▷🦆
题解中提到的剪枝策略`如果当前成本已经超过已知最小值,则剪枝`是如何具体实现的?能否详细解释这种剪枝的逻辑?
▷🦆
题解估算最少还需要的交换次数时使用了`(diff + 1) // 2`,这个计算公式是如何得出的?它依据的是什么原理?
▷相关问题
情侣牵手
n
对情侣坐在连续排列的 2n
个座位上,想要牵到对方的手。
人和座位由一个整数数组 row
表示,其中 row[i]
是坐在第 i
个座位上的人的 ID。情侣们按顺序编号,第一对是 (0, 1)
,第二对是 (2, 3)
,以此类推,最后一对是 (2n-2, 2n-1)
。
返回 最少交换座位的次数,以便每对情侣可以并肩坐在一起。 每次交换可选择任意两人,让他们站起来交换座位。
示例 1:
输入: row = [0,2,1,3] 输出: 1 解释: 只需要交换row[1]和row[2]的位置即可。
示例 2:
输入: row = [3,2,0,1] 输出: 0 解释: 无需交换座位,所有的情侣都已经可以手牵手了。
提示:
2n == row.length
2 <= n <= 30
n
是偶数0 <= row[i] < 2n
row
中所有元素均无重复