我现在有一个测试,这是其中一个问题:
输入
迷宫中的游览地点从1到n。入口和 出口分别对应于数字1和数字n;剩余的 数字对应于过境点。请注意,没有死角 连接一对交叉点的连接数不超过一个。 对于每个测试用例,第一行给出n和连接数 在交叉点之间(m)。然后,在以下m行中的每一行中,找到一对 对应于两个交叉点之间连接的整数。
输出
对于每个测试用例,您的实现应输出一行 包含"发现!",如果有可能通过访问每个到达出口 穿过一次或者#34;该死的!"否则。其他测试用例可能会随之而来。
约束
示例输入:
8 13
1 2
1 3
2 3
2 4
3 4
3 5
4 5
4 6
5 6
5 7
6 7
6 8
7 8
8 8
1 2
1 3
2 4
3 5
4 6
5 7
6 8
7 8
示例输出:
Found!
Damn!
我使用一种DFS算法解决了这个问题,但我有几个问题。
使用DFS算法,我实现了一个递归函数,它在给定节点中启动并尝试访问每个节点一次,最后一个节点必须是退出节点。我现在没有完整的代码,但它是这样的:
findPath(int current node, int numVisitedNodes, int *visited){
int *tmpVisited = copyArray(visited); //copies the visited array to tmpVisited
//DFS algo here
}
每次递归调用都会复制访问过的节点数组。我这样做是因为当它找到无效路径并且递归返回到原点时,它仍然可以继续,因为没有人覆盖被访问节点列表。
有没有更好的方法呢?
你会如何解决? (如果需要,您可以提供代码)
答案 0 :(得分:0)
HashSet操作复杂度为O(1)。如果每个交叉点都是不同的,则复杂度为O(n ^ 2),这是该算法的最坏情况复杂度。空间复杂度为O(n),没有递归,因此没有内存的递归开销。
粗略地说,每个节点只访问一次。
使用有效可达集的Java代码如下。
public class ZeManel {
public static void main(String[] args) {
Integer[][] input = {{1,2},{2,3},{4,6}};
zeManel(input);
}
public static void zeManel(Integer[][] input){
List<Set<Integer>> paths = new ArrayList<Set<Integer>>();
int max = 0;
for(int i = 0;i < input.length;i++) {
max = input[i][0] > max ? input[i][0] : max;
max = input[i][1] > max ? input[i][1] : max;
boolean inPaths = false;
for (Set<Integer> set : paths) {
if(set.contains(input[i][0]) || set.contains(input[i][1])) {
set.add(input[i][0]);
set.add(input[i][1]);
inPaths = true;
break;
}
}
if(!inPaths) {
Set<Integer> path = new HashSet<Integer>();
path.add(input[i][0]);
path.add(input[i][1]);
paths.add(path);
}
}
for (Set<Integer> path : paths) {
if(path.contains(1) && path.contains(max)) {
System.out.println("Found!");
return;
}
}
System.out.println("Damn!");
}
}
答案 1 :(得分:0)
这是我在测试期间的实施:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
# define N 21
# define M 32
int i;
int adj[N][N];
int count = 0;
int findPath(int numNodes, int currentNode, int depth, int *visited){
visited[currentNode] = 1;
if(currentNode == numNodes - 1 && depth == numNodes){
return 1;
}
if(depth > numNodes)
return -1;
int r = -1;
if(depth < numNodes){
count++;
int *tmp = (int*) malloc(numNodes*sizeof(int));
for(i = 0; i < numNodes; i++)
tmp[i] = visited[i];
for(i = 0; i < numNodes; i++){
if(adj[currentNode][i] == 1 && tmp[i] == 0 && r == -1){
if(findPath(numNodes, i, depth + 1, tmp) == 1)
r = 1;
}
}
free(tmp);
}
return r;
}
int main(){
int numLigacoes, a, b, numNodes;
int *visited;
while (scanf("%d %d", &numNodes, &numLigacoes) != EOF){
visited = (int*) malloc(numNodes*sizeof(int));
count = 0;
memset(adj, 0, N*N*sizeof(int));
memset(visited, 0, numNodes*sizeof(int));
for (i = 0; i < numLigacoes; i++){
scanf("%d %d", &a, &b);
adj[a - 1][b - 1] = 1;
adj[b - 1][a - 1] = 1;
}
if(findPath(numNodes, 0, 1, visited) == 1)
printf("Found! (%d)\n", count);
else
printf("Damn! (%d)\n", count);
free(visited);
}
return 0;
}
您怎么看?