【问题标题】:Number which occurs only once in the array [duplicate]在数组中仅出现一次的数字[重复]
【发布时间】:2011-06-13 22:34:29
【问题描述】:

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

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

例子

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

应该返回 4

【问题讨论】:

    标签: algorithm


    【解决方案1】:
    1. 新建int i = 0
    2. XOR 每一项都带有i
    3. 在所有迭代之后,i 中将有预期的数字

    【讨论】:

    • O__O 我可以问一下这个解决方案对这里的每个人来说都那么明显吗?!!这几天我怎么也想不到……
    • @Mehrdad:不知道。因为是琐事问题?
    • @zerkms:你是说琐事还是琐事?无论哪种方式,但是...关于如何学习思考此类问题的解决方案的任何建议是您以前从未见过的? (我想你需要聪明点……不过我不确定我有那么聪明。:()
    • @Mehrdad:这个问题反复出现。这是一些编程知识,也是其中之一“啊哈!”第一次看到它的瞬间。
    • @zerkms:我发誓我可以在不知道这个事实的情况下完成我的一生编程...... @Blastfurnace:是的,它绝对是:)
    【解决方案2】:

    设数组中只出现一次的数字为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;
    } 
    

    【讨论】:

    • @Prasoon:很好的解决方案,Prasoon :-)
    • @Prasoon:顺便问一下,函数模板有必要吗? sizeof(a)/sizeof(a[0]) 还不够?
    • @Nawaz:是的,这就够了。仍然......:P
    • @Nawaz:这个模板方法很有用,已经以std::end()的形式包含在C++0x中
    • @zerkms :什么不公平? :-o
    【解决方案3】:

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

    代码将类似于(在 C# 中):

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

    【讨论】:

      【解决方案4】:

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

      但更简单的方法是将双键设置为零或当前格式不可能的值。也取决于编程语言,因为与 c# 不同,您不能在 c++ 中更改键类型。

      【讨论】:

      • 几个基于 XOR 的 O(n) 解决方案已经发布
      • 在不重新加载页面的情况下,无法确定是否发布了答案。但这是你的真相。
      • 其实是有办法的。当您正在写一个答案并且已经发布了另一个答案时 - 您应该会在顶部看到一个关于新答案的栏,带有将它们加载到当前页面的按钮(无需重新加载)。
      • 我开始怀疑不仅 iPad 裁剪代码 sn-ps 溢出,而且也没有加载该栏。感谢您的提示!
      【解决方案5】:

      zerkms 在 C++ 中的回答

      int a[] = { 1,2,3,4,3,1,2 };
      
      int i = std::accumulate(a, a + 7, 0, std::bit_xor<int>());
      

      【讨论】:

        【解决方案6】:

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

        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();
            }
        }
        

        【讨论】:

        • 哈希容器在即将到来的 C++0x 中为 std::unordered_setstd::unordered_map。当前的编译器已经将这些作为 TR1 库扩展。
        • 为了完整起见,虽然不是核心语言的一部分,但如果您在 POSIX 系统上,hcreate / hsearch 可用linux.die.net/man/3/hsearch
        猜你喜欢
        • 1970-01-01
        • 2010-11-08
        • 1970-01-01
        • 2012-08-11
        • 2019-04-02
        • 1970-01-01
        • 1970-01-01
        • 2016-07-08
        • 1970-01-01
        相关资源
        最近更新 更多