将Primitive int数组转换为list

时间:2011-09-23 14:35:34

标签: java algorithm

我正在尝试解决以下问题。有两个大小为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)。有没有更好的算法。

由于

9 个答案:

答案 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)

  1. 将两个数组放入一个数组
  2. XOR
  3. 所有相同的项目都将自行删除,单个元素将是最后一个。

答案 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);