我如何reduce
Map<Integer, List<Integer>>
?
让reduce
'd地图成为Integer
List<Integer>
的每个 0 --> (0)
1 --> (1, 2)
2 --> (2, 1)
值唯一且不重复的地图。
示例:
地图A:
0 --> (0)
1 --> (1, 2)
会减少到:
0 --> (0)
2 --> (2, 1)
或
reduced
请注意,删除键1或2是可以接受的,因为它会生成0 --> 0
映射。
编辑:当元素映射到自身时,它应该保持独立,例如{{1}}。但是,当多个值具有共同的Integer时,它们应该合并。
答案 0 :(得分:1)
试试这个
class ReducedMap extends HashMap<Integer, List<Integer>> {
private Set<Set<Integer>> set = new HashSet<Set<Integer>>();
@Override
public List<Integer> put(Integer key, List<Integer> value) {
Set<Integer> set = new HashSet<Integer>(value);
if (!this.set.add(set)) {
return new ArrayList<Integer>(set);
}
return super.put(key, value);
}
...
答案 1 :(得分:0)
保留一个ArrayList,让我们调用它&#34;合并&#34;。
您应该使用HashSet来检测重复值。检查一个元素(列表中的值)是否在HashSet中,如果是,则忽略它,否则将其放入HashSet并将其添加到&#34; merged&#34; ArrayList中。
显然,您必须在此逻辑的开头添加一个案例,以便不考虑元素是否映射到自身。
算法如下所示:
声明地图&gt;叫&#34; ret&#34;和一个叫做#34的ArrayList合并&#34;和一个名为&#34; duplicate_checker&#34;
对于输入地图中的每个列表
2.1如果它映射到自身,则将其放入&#34; ret&#34;
2.2否则,对于当前列表中的每个元素,如果它不在&#34; duplicate_checker&#34;然后将其添加到&#34;合并&#34;
Put&#34;合并&#34;到&#34; ret&#34;
希望这有帮助。
答案 2 :(得分:0)
这样的事情应该有效。
版本#2,第一个有错误。
我会使用配对类,因为我们要从地图中提取所有条目并将它们放在配对的矢量中。
private static class Pair {
public Pair(Integer k, List<Integer> l) {
this.k = k;
this.s = new HashSet<Integer>();
this.s.addAll(l);
}
public Integer k;
public Set<Integer> s;
}
接下来,我们需要一种方法来检查两个集合是否有一些共同的元素。
public static boolean intersect(Set<Integer> a, Set<Integer> b) {
Set<Integer> tmp = new HashSet<Integer>(a);
tmp.retainAll(b);
return !tmp.isEmpty();
}
缩小方法采用地图并返回一个新的缩小地图。
public static Map<Integer, List<Integer>> reduce(Map<Integer, List<Integer>> m) {
首先我们将地图转换为对的数组;这将允许有效的迭代和消除键。
int cnt = 0;
Pair[] entries = new Pair[m.size()];
for (Integer k : m.keySet()) {
List<Integer> l = m.get(k);
entries[cnt] = new Pair(k, l);
++cnt;
}
然后我们针对任何其他条目测试每个对;如果他们有共同的元素,我们删除后者,但首先我们将它合并到前者。
for (int i = 0; i < m.size(); ++i) {
for (int j = i + 1; j < m.size(); ++j) {
if (entries[i] != null && entries[j] != null && intersect(entries[i].s, entries[j].s)) {
Set<Integer> si = entries[i].s;
Set<Integer> sj = entries[j].s;
si.addAll(sj);
entries[j] = null;
}
}
}
最后,我们将数组转换回地图,跳过已删除的元素。
Map<Integer, List<Integer>> r = new HashMap<Integer, List<Integer>>();
for (int i = 0; i < m.size(); ++i)
if (entries[i] != null)
r.put(entries[i].k, new ArrayList<Integer>(entries[i].s));
return r;
}