找到数组中唯一的未配对元素

时间:2010-04-15 09:42:34

标签: algorithm

埃森哲面试问题:

您已获得一个大小为2n+1的数组,其n对整数(可以是+ve-ve0)和一个未配对元件。

您如何找到未配对的元素?

配对意味着重复。因此(3,3)是一对,(3,-3) 一对。

10 个答案:

答案 0 :(得分:96)

获取所有元素的XOR

对将取消

a XOR a = 0

,结果将是唯一不成对的元素

0 XOR a = a

如果可以销毁阵列,你可以XOR相邻的元素。完成后,数组的最后一个元素具有未配对的元素:

N = Num of elements in array.
for( i=1 to N )
   arr[i] ^= arr[i-1];    
print arr[N-1]

如果不能销毁数组,可以使用变量来保存结果:

N = Num of elements in array.
Unpaired = arr[0];
for( i=1 to N )
   Unpaired = Unpaired ^ arr[i];    
print Unpaired

C函数做同样的事情:

int findUnpaired(int *arr,int len) {
 int i;                  // loop counter.
 int unpaired;           // to hold the unpaired element.

 unpaired = arr[0];      // initialize it with the 1st array ele.

 for(i=1;i<len;i++) {    // loop for all remaining elements.
    unpaired ^= arr[i];  // XOR each element with the running XOR.
 }
 return unpaired;        // return result.
}

答案 1 :(得分:3)

替代解决方案,在O(n)和O(n)空间中查找所有唯一值:

  

初始化哈希表。
  对于数组中的每个值,检查Hash表中是否存在该值,如果存在,则将其删除,如果不存在,则添加它。
  返回值是哈希表中的所有项目。

如果重复出现的值可以重复多次,则可以轻松修改为使用字典。

答案 2 :(得分:3)

带有XOR解决方案的单行Linq示例:

Demo on DotNetFiddle

public static void Main()
{
    int[] tab = { 1, 2, 3, 2, 1 };
    Console.WriteLine(GetSingle(tab));
}

private static int GetSingle(IEnumerable<int> tab)
{
    return tab.Aggregate(0, (current, i) => current ^ i);
}

为了娱乐和利润

编辑:

此代码段的解释。

var a = 2;
var b = 2;
Console.WriteLine(a ^ b); // will print 0
// because x ^ x == 0

var c = 3;
Console.WriteLine(a ^ b ^ c); // will print 3
// because 0 ^ x == x

Console.WriteLine(0 ^ a); // guess the output
// get it? :)
// Now, lets aggregate this enumerable ;)

答案 3 :(得分:3)

最好的答案是XOR运算符。换句话说,另一种方法是,如果允许对数组进行排序,则对其进行排序并比较相邻的整数。这假设所有整数都出现两次,其中一个整数出现一次。

// Random array of integers
int[] arr = {1, 2, 3, 4, 5, 6, 7, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9};

// Sort the array.
Arrays.sort(arr);

// Array now looks like: 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 9 9 
// Cycle through array comparing adjacent values.
for(int i = 0; i < arr.length; i++){

    // This would mean the single number was the last element in the array.
    if(i == arr.length-1)
        singleNum = arr[i];

    // If the adjacent elements are the same, skip foward. 
    if(i < arr.length-1 && arr[i] == arr[i+1])
        i ++;
    else
        // Otherwise, you found the single number.
        singleNum = arr[i];
}

答案 4 :(得分:2)

这是一个简单的LINQ解决方案,可以轻松扩展以提供每个唯一元素的出现次数:

     int[] numbers = { -1, 0, 1, 2, 3, 4, 5, 4, 3, 2, 1 };

     var numberGroups =
         from n in numbers
         group n by n into g
         select new { Number = g.Key, IsPaired = g.Count() == 2 };

     Console.WriteLine("Unpaired elements:");
     foreach (var group in numberGroups)
     {
        if (!group.IsPaired)
           Console.WriteLine(group.Number);
     }

输出:

Unpaired elements:
-1
0
5

答案 5 :(得分:2)

在给定数组的所有元素中执行XOR

def unpaired(arr):
    result = 0
    for i in arr:
        result = result^i
    return result

答案 6 :(得分:0)

这也是一个很好的解决方案。在这个例子中,我们有一个循环段落。

function getUpaired(arr) {
    var obj = {};
    for (var i = 0; i < arr.length; i++) {
        if (typeof obj[arr[i]] !== 'undefined') {
            delete obj[arr[i]];
            continue;
        }
    obj[arr[i]] = i;
    }
    return Number(Object.keys(obj)[0]);
}
getUpaired([0,0,2,1,3,2,1]);

答案 7 :(得分:0)

使用JavaScript的最佳解决方案,花了我一些时间。

    var singleNumber = function(nums) {
       return nums.reduce((a,b) => a^b);
    };

使用reduce,代码将累加所有数字,但是由于 使用XOR的参数(a,b)互相抵消,只有没有参数的数字 被退回。

答案 8 :(得分:0)

如果您使用的是Swift,则可以使用以下代码找到未配对的元素

func findUnpaired(_ arr: [Int]) -> Int {
    return arr.reduce(0, +)
}

答案 9 :(得分:0)

上述问题的Java解决方案:

public int singleNumber(int[] nums) {
    int result = nums[0];
    for(int i = 1; i < nums.length; i++) {
        result = result^nums[i];
    }
    return result;
}