我在下面写了一个示例代码,在无序列表中找到缺失的数字。例如{5,2,3}应该返回{1,4}。我的问题是,使用HashMap快速查看是否正确?范围是输入列表中的1和最大数字。
public List<Integer> findMissing(List<Integer> numbers) {
int max = 0;
List<Integer> result = new ArrayList<Integer>();
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
for(Integer num : numbers) {
if(num > max)
max=num;
map.put(num,num);
}
int missingCount=max-numbers.size();
for(int i=1;i<=max;i++) {
if(missingCount == 0) break;
if(!map.containsKey(i)) {
result.add(i);
missingCount--;
}
}
return result;
}
答案 0 :(得分:2)
假设代码中缺少的数字是1..max
中未在numbers
中找到的数字。
代码可以使用,但可以改进:当您只需要维护一组没有与之关联的值的项目时,可以使用HashSet
代替HashMap
。然后您执行set.add(num)
,但您可以使用new HashSet<>(numbers)
构建它,而不是逐个添加项目。然后使用set.contains(i)
检查集合中的数字是否存在。
答案 1 :(得分:0)
将整数放入TreeSet
。 Set.contains()
可让您有效地检查它是否包含给定数字,SortedSet.last()
可让您有效地确定其最大元素。然后使用IntStream.rangeClosed()
遍历您的范围,过滤掉您的集合中包含的每个元素,并将剩下的内容收集到新集合中以返回给调用者。
import static java.util.stream.Collectors.toCollection;
import static java.util.stream.IntStream.rangeClosed;
import java.util.Collection;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
Set<Integer> missing(Collection<Integer> collection) {
SortedSet<Integer> set = new TreeSet<>(collection);
return rangeClosed(1, set.last()).boxed()
.filter(i -> !set.contains(i))
.collect(toCollection(TreeSet::new));
}
我接受Collection
而不是List
,因为List
意味着订单,我认为订单更加通用,你说这是不重要的。我返回一个Set
来表示不会有任何重复元素,这在这种情况下是有意义的,因为一个数字不能错过多次。