Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/340.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_Arrays_Algorithm - Fatal编程技术网

Java 从两个数组中获取非重复数据的最佳算法

Java 从两个数组中获取非重复数据的最佳算法,java,arrays,algorithm,Java,Arrays,Algorithm,问题:从两个给定数组(而不是排序数组)中查找非重复项。若数组一是{1,2,3},而第二个数组有{2,3,4},那个么结果应该是{1,4} 我所做的:我通过使用Set实现了它。但它似乎是O(n2) 我需要的是:有没有其他的算法可以写得非常优化 我的代码: package src; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.TreeSet; public

问题:从两个给定数组(而不是排序数组)中查找非重复项。若数组一是{1,2,3},而第二个数组有{2,3,4},那个么结果应该是{1,4}

我所做的:我通过使用Set实现了它。但它似乎是O(n2)

我需要的是:有没有其他的算法可以写得非常优化

我的代码:

package src;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.TreeSet;

public class GetNonDuplicate {

    public static void main(String[] args) {

        Integer[] arrayOne = {1, 2, 3};
        Integer[] arrayTwo = {2, 3, 4};
        List<Integer> resultList = new ArrayList<Integer>();

        List<Integer> listOfArrayOne =  new ArrayList<Integer>(Arrays.asList(arrayOne));
        TreeSet<Integer> setOne = new TreeSet<Integer>(listOfArrayOne);
        System.out.println("SetOne is : " + setOne);

        for (Integer elem2 : arrayTwo) {

            boolean exists = setOne.add(elem2);
            System.out.println("For elem2 [" + elem2 + "], exists [" + exists + "]." );
            if (exists) {
                resultList.add(elem2);
            }
        }

        System.out.println(resultList);

        List<Integer> listOfArrayTwo =  new ArrayList<Integer>(Arrays.asList(arrayTwo));
        TreeSet<Integer> setTwo = new TreeSet<Integer>(listOfArrayTwo);
        System.out.println("setTwo is : " + setTwo);

        for (Integer elem1 : arrayOne) {

            boolean exists = setTwo.add(elem1);
            System.out.println("For elem2 [" + elem1 + "], exists [" + exists + "]." );
            if (exists) {
                resultList.add(elem1);
            }
        }

        System.out.println(resultList);

    }

}
包src;
导入java.util.ArrayList;
导入java.util.array;
导入java.util.List;
导入java.util.TreeSet;
公共类GetNonduplate{
公共静态void main(字符串[]args){
整数[]数组={1,2,3};
整数[]数组two={2,3,4};
List resultList=new ArrayList();
List listOfArrayOne=新的ArrayList(Arrays.asList(arrayOne));
TreeSet setOne=新的TreeSet(列表阵列);
System.out.println(“SetOne是:“+SetOne”);
for(整数elem2:arrayTwo){
boolean exists=setOne.add(elem2);
System.out.println(“对于elem2[“+elem2+”],存在[“+exists+”]);
如果(存在){
结果列表添加(elem2);
}
}
System.out.println(结果列表);
List listOfArrayTwo=新的ArrayList(Arrays.asList(arrayTwo));
TreeSet setTwo=新的TreeSet(列表阵列2);
System.out.println(“setTwo是:“+setTwo”);
for(整数elem1:arrayOne){
boolean exists=setTwo.add(elem1);
System.out.println(“对于elem2[“+elem1+”],存在[“+exists+”]);
如果(存在){
结果列表添加(elem1);
}
}
System.out.println(结果列表);
}
}

基本上只使用集合API(即不使用显式迭代)的解决方案是

Integer[]arrayOne={1,2,3};
整数[]数组two={2,3,4};
Set set1=新的HashSet(Arrays.asList(arrayOne));
Set set2=新的HashSet(Arrays.asList(arrayTwo));
Set uniqueTo1=新哈希集(set1);
唯一1.移除所有(set2);
Set uniqueTo2=新哈希集(set2);
唯一2.移除所有(set1);
Set result=新哈希集(uniqueTo1);
结果:addAll(uniqueTo2);
系统输出打印项次(结果);

这应该在
O(n)
时间内运行,除非我遗漏了什么:数组到列表的转换是
O(n)
,正如创建
集一样,
remove
散列集上是常数时间,所以
removeAll(…)
O(n)

对数组中的每种类型的项进行集合。
然后收集那些只有一个项的数组变量,因此,唯一项

数组是否在开始时排序,如您的示例所示?看起来您需要两个数组元素的对称差。如果这是问题所在,请检查此处:对两个数组进行排序并使用两个指针(每个数组一个)迭代它们将是在O(nlogn)时间和O(1)空间中进行排序的一种方法。使用O(n)空间和O(n)时间,您可以制作一个
映射,计算每个数字的所有出现次数,然后只打印计数为1的数字。感谢Mateusz Dymczyk的好主意:)Hi hatchet,虽然我的示例看起来已排序,但根据问题陈述,应该取消排序。这就是为什么我想到使用TreSet而不是HashSet。遗憾的是,它没有添加来自
arrayTwo
的唯一元素,因此它没有得到“4”。感谢James的这个想法。但是仍然在寻找它是否可以更优化。是的,做这件事太晚了,但是我修复了它,我认为它仍然在
O(n)
中运行。James,我们不能选择TreeSet而不是HashSet吗?
删除
树集上的操作是
O(log(n))
,所以
删除所有
都是
O(n log(n))
一般来说速度会慢一些。阿潘,你能详细说明一下吗?找到一种方法,根据相似性(或使它们相等的行为)对项目进行分组,并将它们存储在二维数组中。现在,检查生成的二维数组,查看是否任何块只有一个项。如果它只有一个项,则表示块中的项是唯一的。
    Integer[] arrayOne = {1, 2, 3};
    Integer[] arrayTwo = {2, 3, 4};
    Set<Integer> set1 = new HashSet<>(Arrays.asList(arrayOne));
    Set<Integer> set2 = new HashSet<>(Arrays.asList(arrayTwo));
    Set<Integer> uniqueTo1 = new HashSet<>(set1);
    uniqueTo1.removeAll(set2);
    Set<Integer> uniqueTo2 = new HashSet<>(set2);
    uniqueTo2.removeAll(set1);
    Set<Integer> result = new HashSet<>(uniqueTo1);
    result.addAll(uniqueTo2);

    System.out.println(result);