在给定所有其他数字的情况下,找到仅在数组中出现一次的数字的算法会出现两次

时间:2009-07-07 01:43:13

标签: algorithm language-agnostic

我能想到的是:

ALGO:

  1. 有一个哈希表,用于存储号码及其相关计数
  2. 解析数组并增加数字的计数。
  3. 现在解析哈希表以获取计数为1的数字。
  4. 你能想到比这更好的解决方案吗? 使用O(n)运行时并且不使用额外空间

9 个答案:

答案 0 :(得分:44)

假设您可以XOR这些数字,我相信这是关键,因为有以下属性:

  • XOR是可交换的和关联的(所以它完成的顺序无关紧要)。
  • 编号为XOR的编号始终为零。
  • XOR带有数字的ed将是该数字。

因此,如果您只是XOR所有值一起出现,那么两次出现的所有值都会相互抵消(给出0),剩下的一个值(n)将{{1}使用该结果(0)来提供XOR

n

不需要哈希表,这具有O(n)性能和O(1)额外空间(只有一个小的小整数)。

答案 1 :(得分:34)

Ruby中的答案,假设有一个单身人士,而其他所有人都是两个外表:

def singleton(array)
  number = 0
  array.each{|n| number = number ^ n}
  number
end

irb(main):017:0> singleton([1, 2, 2, 3, 1])
=> 3
顺便说一句,

^是按位XOR运算符。 XOR一切!哈哈哈!

Rampion让我想起了注入方法,所以你可以在一行中做到这一点:

def singleton(array) array.inject(0) { |accum,number| accum ^ number }; end

答案 2 :(得分:13)

“解析数组并增加数字的计数。”

您可以将其更改为“解析数组,如果哈希表中已存在该数字,请从哈希表中删除该数字”。然后第3步就是“获取哈希表中剩余的唯一数字”

答案 3 :(得分:6)

给定一个整数数组,除了一个元素外,每个元素都会出现两次。找一个单一的。 我们可以使用XOR操作。因为每个数字都是XOR本身,结果将为零。因此,我们对数组中的每个整数进行异或,结果是我们想要找到的单个整数。 这是java版本代码:

public class Solution {
    public int singleNumber(int[] A) {
        int res=0;
        for(int i=0;i<A.length;i++){
            res=res^A[i];
        }
        return res;
    }
}

跟进1: 给定一个整数数组,除了一个元素外,每个元素都会出现三次。找一个单一的。 注意: 您的算法应具有线性运行时复杂性。你能不用额外的内存来实现吗? 对于这个问题,我们不能使用XOR操作。解决这个问题的最好方法是使用“位数”。 创建一个32长度的int数组计数[32]。 count [i]表示所有整数的第i位中有多少'1'。如果count [i]可以除以3,那么我们忽略这个位,否则我们取出这个位并形成结果.Below是java版本代码:

public class Solution {
    public int singleNumber(int[] A) {
        int res=0;
        int[] count=new int[32];
        for(int i=0;i<32;i++){
            for(int j=0;j<A.length;j++){
                if(((A[j]>>i)&1)==1){
                    count[i]=count[i]+1;
                }
            }
            if((count[i]%3)!=0){
                res=res|(1<<i);
            }
        }
        return res;
    }
}

跟进2: 给定一个整数数组,除了两个元素外,每个元素都会出现两次。找到两个整数。 解: 首先,我们可以得到结果的XOR中所有整数。(假设它是c) 其次,从最低有效位到最高有效位,找到第一个'1'位置(假设位置是p)。 第三,将整数分为两组,p组在一组中为“1”,在另一组中为“0”。 第四,对两组中的所有整数进行异或,结果是我们想要的两个整数。

答案 4 :(得分:2)

我正在窃取Michael Sofaer's answer并在Python和C中重新实现它:

的Python:

def singleton(array):
    return reduce(lambda x,y:x^y, array)

C:

int32_t singleton(int32_t *array, size_t length)
{
    int32_t result = 0;
    size_t i;
    for(i = 0; i < length; i++)
        result ^= array[i];
    return result;
}

当然,C版本仅限于32位整数(如果您愿意,可以简单地将其更改为64位整数)。 Python版本没有这样的限制。

答案 5 :(得分:2)

这是Python中的一个解决方案,它可以胜过Ruby的大小(以及可读性,IMO):

singleton = lambda x: reduce(operator.xor, x)

答案 6 :(得分:1)

Python 3.1解决方案:

>>> from collections import Counter
>>> x = [1,2,3,4,5,4,2,1,5]
>>> [value for value,count in Counter(x).items() if count == 1 ][0]
3
>>> 
  • 水稻

答案 7 :(得分:0)

Algo 2:

  1. 对数组进行排序。
  2. 现在解析数组,如果连续2个数字不相同,我们得到了数字。
  3. 这不会占用额外的空间

答案 8 :(得分:0)

这不符合“没有额外空间”的费用,但除非数字以某种方式排序,否则会削减空间。

在Python中:

arr = get_weird_array()
hash = {}

for number in arr:
   if not number in hash:
     hash[number] = 1
   else:
     del hash[number]

for key in hash:
    print key