在无序列表中查找缺少的数字

时间:2015-12-02 23:00:24

标签: java

我在下面写了一个示例代码,在无序列表中找到缺失的数字。例如{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;
}

2 个答案:

答案 0 :(得分:2)

假设代码中缺少的数字是1..max中未在numbers中找到的数字。

代码可以使用,但可以改进:当您只需要维护一组没有与之关联的值的项目时,可以使用HashSet代替HashMap。然后您执行set.add(num),但您可以使用new HashSet<>(numbers)构建它,而不是逐个添加项目。然后使用set.contains(i)检查集合中的数字是否存在。

答案 1 :(得分:0)

将整数放入TreeSetSet.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来表示不会有任何重复元素,这在这种情况下是有意义的,因为一个数字不能错过多次。