【发布时间】:2018-11-07 22:51:54
【问题描述】:
我有一个包含一些重复元素的数组,如下所示:
找到第二次出现的索引最小的第一个重复数字。换句话说,如果有超过 1 个重复的数字,则返回第二次出现的索引比另一个数字的第二次出现的索引更小的数字。如果没有这样的元素,返回 -1
对于 a = [2, 1, 3, 5, 3, 2],输出应该是 firstDuplicate(a) = 3.
有 2 个重复项:数字 2 和 3。第二次出现的 3 比第二次出现的 2 的索引更小,所以答案是 3。
我试过了:
int firstDuplicate(int[] a) {
Set<Integer> set = new HashSet<>();
Map<Integer, Integer> hm = new HashMap<Integer,Integer>();
Map.Entry<Integer, Integer> min = null;
for(int i=0;i<a.length;i++){
// if(!hm.containsKey(a[i]))
hm.put(a[i],i);
}
for(Map.Entry<Integer,Integer> entry : hm.entrySet()){
if(min == null || entry.getValue() < min.getValue()){
min = entry;
}
}
return min == null ? new Integer(-1) : min.getKey();
}
没有成功,但我在网上找到了另一个解决方案,如下所示:
int firstDuplicate(int[] a) {
Set<Integer> set = new HashSet<>();
Map<Integer, Integer> hm = new HashMap<Integer,Integer>();
Map.Entry<Integer, Integer> min = null;
for(int i=0;i<a.length;i++){
if(set.add(a[i])==false && !hm.containsKey(a[i]))
hm.put(a[i],i);
}
for(Map.Entry<Integer,Integer> entry : hm.entrySet()){
if(min == null || entry.getValue() < min.getValue()){
min = entry;
}
}
return min == null ? new Integer(-1) : min.getKey();
}
谁能在这里解释一下 Hashset 的使用,因为它不允许重复,所以 if 条件如何可行。
【问题讨论】:
-
它基本上计算一个哈希图,其键是元素,值是其副本的索引。然后它计算在 hashmap 中的最小索引搜索。
-
Set.add将返回false如果集合中已经包含您要添加的对象。因此,通过检查返回值是否为false,您可以检查对象是否已经在集合中。如果它还没有出现在集合中(并且是第二次出现,而不是以后出现),则将其位置保存在地图中。这会生成一个包含所有重复项及其首次出现的地图。现在,您只需查看哪个是第一个双倍就完成了。您可以通过一些流逻辑大大缩短此代码,但老实说,或者仅返回第一个 false,因为这显然是最早的重复...