我有一个代表道路的行列表,每条道路都有一个“StartingPoint”和一个“EndingPoint”。我的目标是找到每条道路的“下一步”道路。 如果道路的起点或终点位于另一条道路的起点或终点之上,那么道路就是另一条道路。例如:
道路A:起点:(0,0)和终点(2,0)
道路B:起点:(2,0)和终点(5,0)
C路:起点:(2,0)和终点(4,2)
所以道路接下来将是:
下一个{B,C}
B NEXT {A}
C NEXT {A}
我现在的algorthim通过比较道路的每个起点到另一条道路的起点和终点,在O(n ^ 2)中进行。怎样才能让这更快。我认为整理道路可能有用,但我不确定。请告诉我你的想法!
注意:那些使用Hashmap<Start/EndPoint,Road>
解决方案的人仍然是O(N ^ 2)。
答案 0 :(得分:3)
这取决于你想要对结果做什么。计算结果的大小为O(#roads^2)
。这意味着如果你想迭代它,那么你最多需要O(#roads^2)
。这就是说,如果你只想回答诸如“返回给定道路的所有邻接”之类的问题,那么你可以使用你实现的算法在O(#roads)
中做到这一点。
答案 1 :(得分:0)
在Java中,HashMap<XYPoint, HashSet<Road>> endPoints
和另一个HashMap<Road, HashSet<Road> next
就足够了;假设您的Road对象有一个结尾并且开始XYPoint
s。逻辑如下:
for each road R,
add it, using its starting point, to the endPoints map; and
for each road X with a co-incident endpoint,
next.put(R, X); next.put(X, R);
add it, using its ending point, to the map endPoints map; and
for each road X with a co-incident endpoint,
next.put(R, X); next.put(X, R);
在此过程结束时,您的next
地图将包含每条道路的下一条道路。您只需迭代此映射即可生成所需的输出。
如果没有下一条道路,则算法为O(n)。在最坏的情况下(所有道路都有相同的起点和终点),它是O(n ^ 2);你可以通过为你的Roads使用合适的equals / hashcode来消除这种情况,代价是一些额外的复杂性(你需要计算重复次数)。
答案 2 :(得分:0)
在我看来,最简单的方法是创建一个类Cell,它代表某个点,如(x; y)。覆盖Cell的equals和hashCode,然后简单地将Cell对象存储在HashMap中,以保证检索其元素的高速度。
答案 3 :(得分:0)
有一个O(n log n)算法,我不确定是否有更好的算法。
你可以:
1)创建一个Point类,它由一个2D点和一个指向道路的指针组成,它具有一个端点(起点或终点)。
2)创建一个比你的道路集合大两倍的数组
3)循环遍历所有道路,并添加一个表示数组的起点或终点的点 - 将点指向返回创建它的道路。
4)使用您选择的排序对数组进行排序。你可以使用很多排序功能,但是既然你要编写代码,我会说你先用y排序,然后在相同的y上用x来抢劫。所以:
if ( a.y < b.y ) return -1;
if ( a.y > b.y ) return 1;
if ( a.x < b.x ) return -1;
if ( a.x > b.x ) return 1;
return 0;
如果你关心速度,那么你应该把它重写为非分支。
5)相邻点可能相同。肯定不是非相邻点。在O(n)时间内运行有序数组。积分返回他们的道路。结合你认为合适。
答案 4 :(得分:0)
如果你允许3件事,你的最终结果的存储不必是大小为O(道路^ 2):
您需要的哈希映射是HashMap<XYPoint, List<Road>>
对于每条道路,存储List<Road>
startList和endList
算法是(伪代码):
For each road in list
For point in [start, end]
Look up List<Road> roadlist from hash map based on point X,Y
If null then
roadlist = new List<Road>
add road to roadlist
add roadlist to hash map
else
add road to roadList
set roadList as either road.startList or road.endList
您只需将每条道路添加到列表两次。假设哈希查找和添加是O(1)那么这应该是O(n)。