我正在尝试解决以下问题。有两个大小为n的阵列A和大小为n + 1的B. A和B具有相同的所有元素。 B有一个额外的元素。找到元素。
我的逻辑是将数组转换为list并检查B中的每个元素是否存在于A中。
但是当我使用原始数组时,我的逻辑不起作用。如果我正在使用
Integer [] a ={1,4,2,3,6,5};
Integer [] b = {2,4,1,3,5,6,7};
我的代码工作正常。
public static void main(String [] args)
{
int [] a ={1,4,2,3,6,5};
int [] b = {2,4,1,3,5,6,7};
List<Integer> l1 = new ArrayList(Arrays.asList(a));
List<Integer> l2 = new ArrayList(Arrays.asList(b));
for(Integer i :l2)
{
if(!l1.contains(i))
{
System.out.println(i);
}
}
}
而且我的逻辑是O(n + 1)。有没有更好的算法。
由于
答案 0 :(得分:20)
它不适用于原始数组的原因是 Arrays.asList 在给定 int [] 时返回 List&lt; Integer []&gt; 而不是列表&lt;整数&gt; 。
Guava 在Ints课程中有答案。是否有一个 asList 方法,它将采用 int [] 并返回列表&lt;整数&gt;
<强>更新强>
int[] a = ...;
int[] b = ...;
List<Integer> aList = Ints.asList(a);
List<Integer> bList = Ints.asList(b);
以上将允许您的代码适用于int [],因为它适用于Integer []。
查看Ints API
答案 1 :(得分:6)
计算每个数组的总和。总和(B) - 总和(A)将为您提供B中的额外元素。
答案 2 :(得分:3)
ArrayList的contains方法实际上效率不高。这个人都有一个O(n)的运行时,所以你的算法有运行时O(n ^ 2)。
我建议将一个数组放在HashSet中(包含O(1)的contains()运行时)。您可以保留其他数组,直接遍历数组。然后你的运行时是O(n)。
<强>更新强> 来自HashSet API doc:
这个类为基本操作(添加,删除,包含和大小)提供恒定的时间性能,假设散列函数在桶之间正确地分散元素。
我认为默认的Integer哈希函数满足要求。
答案 3 :(得分:2)
只是为了感兴趣,因为它会因为数组连接操作而有点复杂,但是另一个操作需要O(n)
答案 4 :(得分:1)
您可以从两个数组中构造两个Set<Integer>
个对象,然后使用removeAll()
来查找额外的元素。
P.S。您似乎认为,您的方法不是O(n)
。对于整个方法为O(n)
,循环的每次迭代必须在恒定时间内执行;我把它作为练习让读者弄清楚是否是这种情况。
答案 5 :(得分:1)
构造一个Set<Integer>
对象。由于Set不能有重复的元素,添加所有A,然后你可以使用Add函数找到一个在B中返回true的条目。很好,很容易。
答案 6 :(得分:1)
最快的方法是使用int[]
,使用Arrays.sort并合并结果。我怀疑它是功课,所以我会把实际的解决方案留给自己。这是O(n * log(n))但常量低于使用包装器对象和集合。
如果您知道值的范围有限,则可以使用BitSet。这将检测到多个差异,仍然是O(n)
如果您知道只有一个区别,请将这些总和与@rossum建议进行比较。
答案 7 :(得分:1)
仅针对那些感兴趣的人,解决rossum逻辑的典型解决方案。但是如果我们有大数字,那么就有可能出现一些溢出问题。
alg很简单,我们从w零值开始,从一次数组中我们从另一个数组中减去我们添加元素,最后我们添加n + 1元素。
这将在O(n)(n是n + 1)
中起作用我假设数组b有更多元素。
long result = 0;
for(int i =0; i < a.length; i++) {
result -= a[i];
result += b[i];
}
result += b[a.length];
结果我们有了不同之处。
编辑:
哈罗德提出的更好的解决方案,我们不需要担心记忆。
int result = 0;
for(int i =0; i < a.length; i++) {
result ^= a[i] ^ b[i];
}
result ^= b[a.length];
答案 8 :(得分:0)
如果你想转换一个 int 数组(不是整数),使用 IntStream:
int[] arr = {15, 13, 7, 4, 1, 5, 19, 18, 7, 7, 12, 15};
List<Integer> arrayList = IntStream.of(arr).boxed().collect(Collectors.toList());
System.out.println(arrayList);