破解保险箱
难度:
标签:
题目描述
代码结果
运行时间: 30 ms, 内存: 16.5 MB
/*
题目思路:
利用 De Bruijn 序列来生成所有可能的 n 位组合的最短序列。使用 Java Stream API 实现。
*/
import java.util.*;
import java.util.stream.Collectors;
public class SafeCrackerStream {
public String crackSafe(int n, int k) {
String start = String.join("", Collections.nCopies(n - 1, "0"));
Set<String> visited = new HashSet<>();
StringBuilder sb = new StringBuilder();
visited.add(start);
dfs(start, visited, sb, n, k);
sb.append(start);
return sb.toString();
}
private void dfs(String current, Set<String> visited, StringBuilder sb, int n, int k) {
List<Integer> range = IntStream.range(0, k).boxed().collect(Collectors.toList());
range.forEach(i -> {
String next = current + i;
if (visited.add(next)) {
dfs(next.substring(1), visited, sb, n, k);
sb.append(i);
}
});
}
public static void main(String[] args) {
SafeCrackerStream sc = new SafeCrackerStream();
System.out.println(sc.crackSafe(2, 2)); // 输出: 01100
}
}
解释
方法:
这道题目可以使用Hierholzer算法来找到Euler路径,即一条通过图中每条边恰好一次的路径。图中的节点表示密码的前n-1位,而边则表示可能的n位密码。算法的核心是构建一个有向图,图的节点表示长度为n-1的序列,每个节点会有k条出边,这些出边对应在该序列后添加一个数字形成的n位序列。解题过程首先构建图的邻接表,然后使用深度优先搜索遍历图来寻找Euler回路,最后将这个回路转换成对应的密码序列。
时间复杂度:
O(k^n)
空间复杂度:
O(k^n)
代码细节讲解
🦆
在解题过程中,你是如何确定使用Hierholzer算法来寻找Euler路径的?
▷🦆
Hierholzer算法适用于哪些类型的图,即什么条件下图中存在欧拉回路或路径?
▷🦆
在算法中,你如何构建图的节点和边?特别是如何从节点表示长度为n-1的序列到节点有k条边的过程是如何实现的?
▷🦆
在深度优先搜索(DFS)过程中,如何确保每条边只被访问一次,从而满足Euler路径的要求?
▷