【发布时间】:2016-03-14 06:11:56
【问题描述】:
我需要将[Integer, List<Integer>] 键映射到Integer。考虑到速度是关键,我已经考虑了以下方法,并且正在努力找出最有益的方法。
为什么我需要这个?
有一个二维数组。每行是出站的线路数。每行包含来自地铁的线路。因此,地铁站编号为 0,1,... 所有行都有相同数量的元素(来自所有车站的相同数量的线路)。行的第 0 个索引给出了第 0 行的目的地。行的第 1 个索引给出了乘坐 1 号线的目的地,... k 站列表的第 r 个元素给出了从 k 站乘坐 r 线可直接到达的站。现在,假设您在其中一个车站迷路了。无论您在哪个车站,如果您采用某种路径组合,您将到达一个公共车站。这称为会面路径。对于给定的地铁配置,我需要找出是否有可能的会面路径。例如。对于subway = [[2, 1], [2, 0], [3, 1], [1, 0]],从任何车站乘坐 line1 然后 line0,最终到达 station2。所以 [1,0] 将是一条会议路径。
我生成了一组路径,看起来像 [[0],[1],[0,0],[0,1],[1,0],[1,1],[0,0, 0],[0,0,1],...]。我必须遍历每个站的路径,看看我是否在所有站的同一站结束。比如说,我们考虑 station0,并且正在考虑 path[0,0,1]。我已经遍历了路径 [0,0]。无需再次遍历该部分,我可以使用遍历 [0,0] 后的任何结果并从该点取 line1,最终到达我的新目的地。这就是为什么我需要缓存([startStation,pathList],destination)。此外,如果这种寻找会合路径的方式对于比如8度路径不起作用,我们需要检查关闭某个站点是否会导致会合路径。更是如此,为什么我要使用 [startStation, pathList] 作为键。完整问题陈述的链接在帖子的末尾。
第一种方法:创建一个新的unmodifiableList,将第0 个索引处的值作为上述Integer,其余作为List<Integer>。我会用这个unmodifiableList 作为键。
第二种方法:创建一个新的unmodifiableList,将第0 个索引处的值作为上述Integer,将第一个索引作为List<Integer> 的不可修改副本的hashCode。我会用这个unmodifiableList 作为键。 [Thilo 在 cmets 中正确指出这种方法会导致冲突]。
第三种方法:[嵌套映射] 创建一个从 Integer 到另一个 HashMap 的映射,该映射从 List<Integer> 映射到 Integer。 [类似于接受的答案here]
第四种方法:创建一个以Integer和List<Integer>为字段的对象,并覆盖equals和hashCode方法。这将作为关键。
我觉得第三种方法是最简单的,并且会生成最易读的代码。我正在努力权衡所有 4 种设计的利弊。速度是关键。
这是关于 Google Foobar 挑战的一个问题 [problem]
【问题讨论】:
-
如果您需要地图,为什么不使用
Map<Integer, List<Integer>>?访问时间为~O(1) -
第二种方法在哈希码冲突的情况下不起作用。
-
“速度是关键”——关键是什么?在这种情况下,您确定 Java Map 是您想要的吗?
-
@fge Foobar 在某个点后超时。所以,我意识到我需要缓存一些数据来加快处理时间。我需要一个字典数据结构,因为我需要一个(键,值)组合才能将处理时间从 O(n) 减少到 O(1)。
-
@Prashant 我需要一个 (Integer-List
) 作为键和 Integer 作为值。
标签: java dictionary hashmap