4 回答
TA贡献1803条经验 获得超6个赞
我提供以下解决方案。
迭代第一个数组,找出它的最小值和最大值。
创建长度为max-min+1 的临时数组(您可以使用max + 1作为长度,但当您有值时,例如从 100k 开始,它可能会遵循开销)。
迭代第一个数组并标记临时数组中的现有值。
迭代第二个数组并取消标记临时数组中的现有值。
将临时数组中的所有标记值放入结果数组。
代码:
public static int[] getUnique(int[] one, int[] two) {
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int i = 0; i < one.length; i++) {
min = one[i] < min ? one[i] : min;
max = one[i] > max ? one[i] : max;
}
int totalUnique = 0;
boolean[] tmp = new boolean[max - min + 1];
for (int i = 0; i < one.length; i++) {
int offs = one[i] - min;
totalUnique += tmp[offs] ? 0 : 1;
tmp[offs] = true;
}
for (int i = 0; i < two.length; i++) {
int offs = two[i] - min;
if (offs < 0 || offs >= tmp.length)
continue;
if (tmp[offs])
totalUnique--;
tmp[offs] = false;
}
int[] res = new int[totalUnique];
for (int i = 0, j = 0; i < tmp.length; i++)
if (tmp[i])
res[j++] = i + min;
return res;
}
TA贡献1810条经验 获得超4个赞
出于学习目的,我们不会添加新工具。
让我们按照你之前的思路,修正第二部分:
// populate the new array with the unique values
for (int i = 0; i < a1.length; i++) {
int count = 0;
for (int j = 0; j < a2.length; j++) {
if (a1[i] != a2[j]) {
count++;
if (count < 2) {
result[i] = a1[i];
}
}
}
}
对此:
//populate the new array with the unique values
int position = 0;
for (int i = 0; i < a1.length; i++) {
boolean unique = true;
for (int j = 0; j < a2.length; j++) {
if (a1[i] == a2[j]) {
unique = false;
break;
}
}
if (unique == true) {
result[position] = a1[i];
position++;
}
}
我假设您实施的“计数”是为了防止误报添加到您的结果数组中(这会结束)。当一个人确定一个数组是否包含 dup 时,他不做“计数”,他只是通过沿着列表向下比较第一个数字和第二个数组,然后如果他看到一个 dup (a1[i] == a2[j]),他会说“哦,它不是唯一的”(unique = false)然后停止循环(break)。然后他会将数字添加到第二个数组中 (result[i] = a1[i])。
所以要尽可能地结合这两个循环:
// Create a temp Array to keep the data for the loop
int[] temp = new int[a1.length];
int position = 0;
for (int i = 0; i < a1.length; i++) {
boolean unique = true;
for (int j = 0; j < a2.length; j++) {
if (a1[i] == a2[j]) {
unique = false;
break;
}
}
if (unique == true) {
temp[position] = a1[i];
position++;
}
}
// This part merely copies the temp array of the previous size into the proper sized smaller array
int[] result = new int[position];
for (int k = 0; k < result.length; k++) {
result[k] = temp[k];
}
TA贡献1805条经验 获得超9个赞
让你的代码工作
如果您更正第二个循环,您的代码工作正常。看看我所做的修改:
//populate the new array with the unique values
int counter = 0;
for (int i = 0; i < a1.length; i++) {
for (int j = 0; j < a2.length; j++) {
if (a1[i] == a2[j]) {
result[counter] = a1[i];
counter++;
}
}
}
我会这样做的方式
现在,这是我如何创建这样的方法,而无需多次检查重复项。往下看:
public static int[] removeDups(int[] a1, int[] a2) {
int[] result = null;
int size = 0;
OUTERMOST: for(int e1: a1) {
for(int e2: a2) {
if(e1 == e2)
continue OUTERMOST;
}
int[] temp = new int[++size];
if(result != null) {
for(int i = 0; i < result.length; i++) {
temp[i] = result[i];
}
}
temp[temp.length - 1] = e1;
result = temp;
}
return result;
}
它不是创建result具有固定大小的数组,而是在每次发现新的重复项时创建一个具有适当大小的新数组。请注意,如果等于,则返回null。a1a2
TA贡献1780条经验 获得超4个赞
您可以使用另一种方法来查看元素是否包含在列表中:
public static boolean contains(int element, int array[]) {
for (int iterator : array) {
if (element == iterator) {
return true;
}
}
return false;
}
您的 main 方法将迭代每个元素并检查它是否包含在第二个元素中:
int[] uniqueElements = new int[a1.length];
int index = 0;
for (int it : a1) {
if (!contains(it, a2)) {
uniqueElements[index] = it;
index++;
}
}
添加回答
举报