Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在具有有限堆的列表中查找重复项_Java_Algorithm - Fatal编程技术网

Java 在具有有限堆的列表中查找重复项

Java 在具有有限堆的列表中查找重复项,java,algorithm,Java,Algorithm,在1和N之间有一个长度为N+1的只读数字列表。 列表中有重复项,但可能还有更多。 例如,N=3,列表中的项目[1,3,1,3] 我需要一个算法来打印重复的项目。(不管项目在其中多少次) 根据上述示例,结果为1,3 我需要一个使用java的解决方案,该解决方案可以使用受限堆(可以在短时间内运行许多项) 我试图创建一个新的HashSet,并将列表中的项添加到该HashSet中,如果该HashSet中已经包含该项,则我已将其保存到ArrayList中 public static void main(S

在1和N之间有一个长度为N+1的只读数字列表。 列表中有重复项,但可能还有更多。 例如,N=3,列表中的项目[1,3,1,3] 我需要一个算法来打印重复的项目。(不管项目在其中多少次) 根据上述示例,结果为1,3 我需要一个使用java的解决方案,该解决方案可以使用受限堆(可以在短时间内运行许多项)

我试图创建一个新的HashSet,并将列表中的项添加到该HashSet中,如果该HashSet中已经包含该项,则我已将其保存到ArrayList中

public static void main(String[] args) {
    List<Integer> list = new ArrayList<>();

    list.add(1);
    list.add(2);
    list.add(3);
    list.add(4);
    list.add(1);
    list.add(2);
    list.add(5);

    Set<Integer> set = new HashSet();
    List<Integer> duplicatedList = new ArrayList<>();   

    for (Integer item : list) {
    if(set.contains(item)) {
        duplicatedList.add(item);
    }
    set.add(item);
}
System.out.println(duplicatedList +" "+ list);
publicstaticvoidmain(字符串[]args){
列表=新的ArrayList();
增加第(1)款;
增加(2);
增加(3);
增加(4);
增加第(1)款;
增加(2);
增加(5);
Set=newhashset();
List duplicatedList=new ArrayList();
用于(整数项:列表){
if(集合包含(项目)){
重复列表。添加(项目);
}
设置。添加(项目);
}
System.out.println(复制列表+“”+列表);

它可以工作,但我认为这不是很有效。对于这个问题,有没有更有效的解决方案?

如果希望限制堆的使用,请从原始列表中删除非重复项,而不是创建新列表。还可以使用跟踪已看到的数字

List<Integer> list = new ArrayList<>(Arrays.asList(1,2,3,4,1,2,5));
int N = list.size() - 1;

BitSet present = new BitSet(N);
for (Iterator<Integer> iter = list.iterator(); iter.hasNext(); ) {
    int value = iter.next();
    if (! present.get(value)) {
        present.set(value);
        iter.remove();
    }
}
System.out.println(list);
如果原始列表是只读的,请像前面提到的那样构建一个新列表

List<Integer> list = Arrays.asList(1,2,3,4,1,2,5);

BitSet present = new BitSet();
List<Integer> duplicatedList = new ArrayList<>();
for (Integer item : list) {
    if (present.get(item))
        duplicatedList.add(item);
    else
        present.set(item);
}
System.out.println(duplicatedList +" "+ list);

主要的改进是使用
位集
而不是
,这依赖于数字的范围被限制在1到N之间,因此使用的空间更少(极端情况除外)。

这里有问题吗?您已经说过“它工作了”。将
if(Set.contains(item))
替换为
if(!集合。添加(项目))
,因此您不需要对每个项目访问两次
集合。除此之外,著名的面试问题将重复的问题限制为一个。在这种情况下,有更有效的算法。当您提前知道重复的数量时,也有有趣的解决方案。总之,“有限的堆”是什么意思?效率不如集合,但如何将列表排序到位?顺便说一句,您肯定错过了大括号。
set.add(item)不幸的是,原始列表是只读的。我不能改变它:/如何移除项目以提高性能以与添加相比?我是C++ AdPt,可能会在java中丢失什么东西,但是从我的观点来看,ARAYLIST应该比删除更有效。l堆使用率,而不是性能,因为我将空间(“有限堆”)解释为“高效”的主要标准,而不是性能。@Andreas如果堆有限,列表很长,您可以尝试多次迭代该列表。从时间复杂度来看,这不是有效的,但这是内存有限且对数据没有限制的唯一解决方案。位集也不是免费的。@DmitryKuzminov True,但
位集
比一个
集合
,具有类似的O(n)时间复杂度,在多次迭代列表的同时满足“更有效的解决方案”的请求,即O(n²)。