从具有奇数个项目的给定数组中查找非重复整数

时间:2019-02-23 06:29:23

标签: java arrays

试图用此代码找出错误。这适用于小样本,但不适用于大量样本(尽管我手中没有大样本)。

该解决方案适用于以下测试。

private static final int[] A = {9,3,9,3,9,7,9};
private static final int[] A2 = {9,3,9};
private static final int[] A3 = {9,3,9,3,9,7,7,2,2,11,9};

@Test
public void test(){
    OddOccurance oddOccurance =new OddOccurance();
    int odd=oddOccurance.solution(A);
    assertEquals(7,odd);
}


@Test
public void test2(){
    OddOccurance oddOccurance =new OddOccurance();
    int odd=oddOccurance.solution(A2);
    assertEquals(3,odd);
}


@Test
public void test3(){
    OddOccurance oddOccurance =new OddOccurance();
    int odd=oddOccurance.solution(A3);
    assertEquals(11,odd);
}

当给定一个具有奇数个整数的数组时(一个整数除外,可以重复其他整数)。解决方案是找到非重复整数。任何其他更好的想法(时间和空间优化)也可以实现。

  public int solution(int[] A) {
    // write your code in Java SE 8
    Map<Integer, List<Integer>> map = new HashMap<>();
    int value = 0;
    //iterate throught the list and for each array value( key in the map)
    // set how often it appears as the value of the map
    for (int key : A) {

        if (map.containsKey(key)) {
            map.get(key).add(value);

        } else {
            List<Integer> valueList = new ArrayList<>();
            valueList.add(value);
            map.put(key, valueList);
        }

    }

    Set<Map.Entry<Integer, List<Integer>>> entrySet = map.entrySet();
    //   en
    for (Map.Entry<Integer, List<Integer>> entry : entrySet) {
        if (entry.getValue().size() == 1) {
            return entry.getKey();
        }
    }

    return 0;

}

更新 查看失败的输出 错误的答案,预期为0 42 错误的答案,预期0为700

似乎它甚至都没有进入for循环,只是返回0

3 个答案:

答案 0 :(得分:1)

如果实际陈述如下,这是一个标准问题:

  

除一个以外,每个数字均出现偶数次;剩余的号码出现一次。

解决方案是取所有数字中的xor。由于每个重复编号都出现偶数次,因此它将自行取消。原因是xor是可交换的:

a xor b xor c = a xor c xor b = c xor b xor a = etc.

例如,对于1, 2, 3, 1, 2

1 xor 2 xor 3 xor 1 xor 2 =
(1 xor 1) xor (2 xor 2) xor 3 =
0 xor 0 xor 3 =
3

答案 1 :(得分:1)

一种方法是创建一个包含每个值的频率的新数组。您可以从遍历初始数组开始计算其中的最大值。

例如,数组{9,3,9,3,9,7,7,2,2,11,9}的最大值为11。使用此信息,创建一个新数组,该数组可以存储初始数组中每个可能值的频率。然后,假设只有一个整数重复一次,则返回频率为1的新数组的索引。此方法应在O(n)中运行,其中n是输入数组的大小。

这是一个实现:

public int solution(int[] inp)
{
    int max = inp[0];

    for(int i = 1; i < inp.length; i++)
    {
        if(inp[i] > max)
            max = inp[i];
    }

    int[] histogram = new int[max + 1]; //We add 1 so we have an index for our max value

    for(int i = 0; i < inp.length; i++)
        histogram[inp[i]]++; //Update the frequency

    for(int i = 0; i < histogram.length; i++)
    {
        if(histogram[i] == 1)
            return i;
    }

    return -1; //Hopefully this doesn't happen
}

希望这会有所帮助

答案 2 :(得分:1)

在没有实际错误消息的情况下,很难知道为什么您的失败。无论如何,随着数组输入变得非常大,您的内部数据结构也会相应地增长,但并不需要。取而代之的是将Integer的数组作为值,我们只能使用一个Integer

public int solution(int[] a) {

    Integer ONE = 1;

    Map<Integer, Integer> map = new HashMap<>();

    for (int key : a) {
        Integer value = (map.containsKey(key)) ? map.get(key) + ONE : ONE;

        map.put(key, value);
    }

    for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
        if (entry.getValue().equals(ONE)) {
            return entry.getKey();
        }
    }

    return -1;
}

我假设奇数数组长度要求是避免长度为2的数组,因为这两个元素都是不可重复的或重复的。

由于我们不需要实际的总数,因此我们可以进一步简化此过程,而只需考虑奇偶校验。这是重做的工作,它使用并使用了该问题的不断发展的新规则,以寻找奇怪的人:

public int solution(int[] a) {

    Map<Integer, Boolean> odd = new HashMap<>();

    for (int key : a) {
        odd.put(key, (odd.containsKey(key)) ? ! odd.get(key) : Boolean.TRUE);
    }

    for (Map.Entry<Integer, Boolean> entry : odd.entrySet()) {
        if (entry.getValue()) {
            return entry.getKey();
        }
    }

    return 0;
}

我们现在知道的失败返回零:

  

A是[1..1,000,000,000]范围内的整数