【发布时间】:2017-08-03 19:40:33
【问题描述】:
我在树上应用 bfs,其中每个节点都有四个堆栈和一个整数。我将它们存储在队列中。我正在使用 HashSet 来存储访问过的节点。因此,在队列中添加节点之前,我正在检查 HashSet 是否包含该节点。但是该程序花费了太多时间来提供输出。我的方法是正确的还是有其他方法可以跟踪访问的节点?当我们不能在数组中表示节点时,Hashset 好吗? 我正在提供我的代码。以下是代表一个节点的状态类。
static class State implements Serializable
{
int c=0;
Stack s[]=new Stack[4];
State()
{
for(int i=0;i<4;i++)
{
s[i]=new Stack();
}
}
}
我的广度优先搜索算法如下代码
static int Bfs(HashSet<state>hs,state st,int n)
{
hs.add(st);
LinkedList<state> queue = new LinkedList<>();
queue.add(st);
while(!queue.isEmpty())
{
state sn=queue.remove();
if(sn.s[0].size()==n)
{
return sn.c;
}
for(int i=0;i<4;i++)
{
if(sn.s[i].size()>0)
{
int f=i;
for(int id:IntStream.range(0, 4).filter(x->(x!=f)).toArray())
{
state tm=(state)deepcopy(sn);
if((tm.s[id].size()==0)||((int)tm.s[id].peek()>(int)tm.s[i].peek()))
{
tm.s[id].push(tm.s[i].pop());
if(!hs.contains(tm))
{
tm.c+=1;
hs.add(tm);
queue.add(tm);
}
queue.add(tm);
}
}
}
}
}
return -1;
}
上面的代码是针对问题“https://www.hackerrank.com/challenges/gena”,就像河内塔一样,有4个栈。我需要将所有磁盘放在第一个堆栈中。因此,在每个双端队列操作中,我从一个堆栈中弹出最后一个元素并将其一个一个地推送到其他堆栈上,并且我在所有堆栈上一个接一个地执行此弹出操作。因此,对于每个状态,都会有 4x3 个邻居。 For 循环只是将所有其他堆栈的索引存储在要推送弹出元素的变量 id 中。
【问题讨论】:
-
向我们展示您的代码
-
这里的问题绝对不是哈希集。你能解释一下所有这些堆栈的含义以及你的循环条件是什么?
-
@templatetypedef 更新以使其更清晰
-
@templatetypedef 如您所见,除了 HashSet.contains() 方法之外,在 while 循环中的 bfs 中没有调用耗时的方法。
-
尽管这里没有很多昂贵的电话,但您正在探索的搜索空间是如此巨大,以至于访问每个州所需的时间可能最终成为瓶颈。
标签: data-structures graph-theory graph-algorithm breadth-first-search