在数组中只出现一次的数字

时间:2011-01-23 06:03:18

标签: algorithm

  

可能重复:
  Finding a single number in a list

给定一组数字,除了一个数字外,其他所有数字都会出现 两次。什么算法应该找到只出现一次的那个数字 阵列

实施例

a[1..n] = [1,2,3,4,3,1,2] 

应该返回4

6 个答案:

答案 0 :(得分:24)

让数组中只出现一次的数字为x

x <- a[1]
for i <- 2 to n
   x <- x ^ a[i]
return x

a ^ a = 0a ^ 0 = a

以来

对中出现的数字会取消,结果会存储在x

使用C ++编写代码

#include <iostream>

template<typename T, size_t N>
size_t size(T(&a)[N])
{
    return N;
}
int main()
{
   int a [] = {1,2,3,4,3,1,2};
   int x = a[0];
   for (size_t i = 1; i< size(a) ; ++i)
   {
      x = x ^ a[i];
   }
   std::cout << x;
} 

答案 1 :(得分:19)

  1. 新建int i = 0
  2. XOR每个项目i
  3. 在所有迭代之后,i
  4. 中会出现预期的数字

答案 2 :(得分:2)

如果您的数量无法合理排序(例如,大整数或表示为字符串的数字),则另一种方法也是O(n)时间,(但是O(n)空间而不是O(1) space)就是简单地使用哈希表。算法如下:

Create a hash table of the same size as the list
For every item in the list:
     If item is a key in hash table
         then remove item from hash table
         else add item to hash table with nominal value
At the end, there should be exactly one item in the hash table

我会做,C或C ++代码,但它们都没有内置的哈希表。(不要问我为什么C ++在STL中没有哈希表,但确实有一个基于哈希表的哈希表红黑树,因为我不知道他们在想什么。)不幸的是,我没有一个C#编译器方便测试语法错误,所以我给你Java代码。但它非常相似。

import java.util.Hashtable;
import java.util.List;

class FindUnique {
    public static <T> T findUnique(List<T> list) {
        Hashtable<T,Character> ht = new Hashtable<T,Character>(list.size());
        for (T item : list) {
            if (ht.containsKey(item)) {
                ht.remove(item);
            } else {
                ht.put(item,'x');
            }
        }
        return ht.keys().nextElement();
    }
}

答案 3 :(得分:1)

我只知道蛮力算法,它是遍历整个阵列并检查

代码就像(在C#中):

k=0;
for(int i=0 ; i < array.Length ; i++)
{
    k ^= array[i];
}
return k;

答案 4 :(得分:1)

zerkms在C ++中的答案

int a[] = { 1,2,3,4,3,1,2 };

int i = std::accumulate(a, a + 7, 0, std::bit_xor<int>());

答案 5 :(得分:0)

您可以对数组进行排序,然后找到没有对的第一个元素。这将需要几个循环进行排序,并需要一个循环来查找单个元素。

但更简单的方法是将双键设置为零或者是当前格式中不可能的值。取决于编程语言,因为你不能像c#那样改变c ++中的键类型。