一种方式做到这一点,是为使用的Set
的removeAll()
或retainAll()
方法。另一种方法是并行迭代阵列,不使用Set
。
易于使用的,前两种方法会使用这个帮手:
private static Set<Integer> asSet(int[] array) {
Set<Integer> set = new HashSet<>();
for (int i : array)
set.add(i);
return set;
}
使用removeAll()
实现:
public static int countDifference(int[] array1, int[] array2) {
// Find distinct elements in array1 that doesn't exist in array2
Set<Integer> distinct1 = asSet(array1);
distinct1.removeAll(asSet(array2));
// Find distinct elements in array2 that doesn't exist in array1
Set<Integer> distinct2 = asSet(array2);
distinct2.removeAll(asSet(array1));
return distinct1.size() + distinct2.size();
}
如果本身保证了阵列不包含重复,然后retainAll()
能找到常见值:
public static int countDifference(int[] array1, int[] array2) {
Set<Integer> common = asSet(array1);
common.retainAll(asSet(array2));
return array1.length + array2.length - 2 * common.size();
}
上述两种实现都不依赖于正在排序的数组。为了消除创建集的开销和所有值的拳击,你可以使用数组的排序,并且并行迭代他们:
public static int countDifference(int[] array1, int[] array2) {
int idx1 = 0, idx2 = 0, count = 0, val;
while (idx1 < array1.length || idx2 < array2.length) {
if (idx1 == array1.length) {
val = array2[idx2];
count++;
} else if (idx2 == array2.length) {
val = array1[idx1];
count++;
} else {
val = Math.min(array1[idx1], array2[idx2]);
if (array1[idx1] != val || array2[idx2] != val)
count++;
}
while (idx1 < array1.length && array1[idx1] == val)
idx1++; // skipping 0 to many instances of val in array1
while (idx2 < array2.length && array2[idx2] == val)
idx2++; // skipping 0 to many instances of val in array2
}
return count;
}
这将是最快,最内存高效的实现。
思想
这可以说是countDifference
会考虑投入3,5,5,7
和3,5,7
有1个差异。如果是这样,那么任何使用Set
是错误的,最后的方法应该if
语句替换内while
循环,或者使用更简单的实现是这样的:
public static int countDifference(int[] array1, int[] array2) {
int idx1 = 0, idx2 = 0, count = 0;
while (idx1 < array1.length && idx2 < array2.length) {
int cmp = Integer.compare(array1[idx1], array2[idx2]);
if (cmp != 0)
count++;
if (cmp <= 0)
idx1++;
if (cmp >= 0)
idx2++;
}
return count + (array1.length - idx1) + (array2.length - idx2);
}
就个人而言,我认为这是正确的解决方案,但这取决于应该如何处理数组中的重复值。如果不存在重复,或者重复被认为是不同的,则这是最好的实施方式,例如,就像上面这个例子中的值5
一样。
您可以按照与'distinctNumberOfItems'方法相同的方式执行此操作。只需添加第二个循环,您可以再次从该集合中删除元素。 – SpiderPig
我该如何开始这样做?我在哪里放置我的循环? – EstelleVeneer
[查找两个数组之间的非重复项与Java]可能的重复(http://stackoverflow.com/questions/19401618/find-non-duplicate-items-between-two-arrays-with-java) –