埃森哲面试问题:
您已获得一个大小为2n+1
的数组,其n
对整数(可以是+ve
,-ve
或0
)和一个未配对元件。
您如何找到未配对的元素?
配对意味着重复。因此(3,3)
是一对,(3,-3)
不一对。
答案 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示例:
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;
}