如何在Array中找到两个重复元素

时间:2011-12-04 05:26:53

标签: java arrays

下面的代码工作正常,但它的复杂性为O(n ^ 2)。是否可以进行O(n)或O(log n)时间。

public class TwoRepeatingElements {
    public static void main(String[] args) {
        Integer array[] = {4, 2, 4, 5, 2, 3, 1, 2};
        findTwoRepeatingElements(array);


    }

    private static void findTwoRepeatingElements(Integer[] array) {
        int i, j;
        for(i = 0; i < array.length-1; i++) {
            for(j = i+1; j < array.length-1; j++) {
                if(array[i] == array[j]) {
                    System.out.println(array[i]);
                }
            }
        }

    }

}

7 个答案:

答案 0 :(得分:2)

显然你不能在O(n)以内找到它,因为你需要扫描整个数组。 您可以将hastable用于O(n)解决方案。

只需将你的元素插入hastable中,当你要插入的元素已经存在时停止。

private static void findTwoRepeatingElements(Integer[] array) {
    Set<Integer> set = new HashSet<Integer>();
    for(int a : array) {
        if(!set.add(a)) {
            System.out.println(a);
            break;
        }
    }
}

答案 1 :(得分:1)

您可以对数组进行排序,然后在相邻位置查找两个相等的数字。

答案 2 :(得分:0)

创建一个临时hashmap并将您遇到的所有值都放入其中。 hashmap的平均查找时间为O(1),因此您将以O(n)结束。

答案 3 :(得分:0)

O(log n)是绝对不可能的,因为你需要至少迭代整个数组一次。

如果您事先知道可能的整数范围,并且它是一个相对较小的范围,您可以使用boolean[]来跟踪您已经看到的整数。那将是O(n + k),其中 k 是范围的大小,因此如果 k 在O(n)中则为O(n)。否则,您可以使用HashSet<Integer>,但这不会保证 O(n)时间。

答案 4 :(得分:0)

此解决方案在O(n)时间内运行,请注意,如果您只需要找到一个重复元素,则可以在找到后立即退出循环:

private static void findTwoRepeatingElements(Integer[] array) {
    Set<Integer> seen = new HashSet<Integer>();
    for (Integer i : array) {
        if (seen.contains(i))
            System.out.println(i);
        else
            seen.add(i);
    }
}

修改

如果你只需要打印一次重复的元素,这个解决方案会使用更多的内存,因为需要两个集合,但它仍然是O(n)。看看这个:

private static void findTwoRepeatingElements(Integer[] array) {

    Set<Integer> seen = new HashSet<Integer>();
    Set<Integer> repeated = new HashSet<Integer>();

    for (Integer i : array)
        if (!seen.add(i) && repeated.add(i))
            System.out.println(i);

}

答案 5 :(得分:0)

与Peter的答案类似,但更好地使用API​​,因此代码更少:

static Integer findFirstRepeatedElement(Integer[] array) {
    Set<Integer> set = new HashSet<Integer>();
    for(Integer a : array) {
        if(!set.add(a)) // returns false if the element is already in the set
            return a;
    }
    return null;
}

编辑:我注意到他现在修复了他以前的非leet实现

答案 6 :(得分:0)

这可以减少到O(n)

int previous =array[0];  
for(int i=1; i less than array.length; i++)    {
   if (previous == array[i] return true;    
   previous =array[i];    
}
return false // outside of loop.

原谅我在手机上的格式