【问题标题】:find the only unpaired element in the array找到数组中唯一未配对的元素
【发布时间】:2011-02-08 07:22:01
【问题描述】:

埃森哲面试题:

您获得了一个大小为2n+1 的数组,其中包含n 一对整数(可以是+ve-ve0)和一个不成对的元素。

如何找到未配对的元素?

配对表示重复。所以(3,3) 是一对,(3,-3) 不是一对。

【问题讨论】:

  • 什么是“对”——你能举个例子吗? IE。 { 3, -3 } 是一对,还是 { 3, 3 } 是一对?
  • 一对总是两个同类。 3 和 -3 不是一对。
  • 一对是问题定义的任何东西。在这种情况下,我认为问题认为 (x, -x) 是一对,它要求找到没有对的数字。然而,澄清会很好。

标签: algorithm


【解决方案1】:

取所有元素中的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 2 3 1 3. 追踪这个例子的算法。当你全部异或时,你会得到 2。
  • 在形式上,xor 是可交换的和关联的,这意味着初始输入的异或顺序与最终结果无关。
  • 方法“返回”(即打印)array[N-1],在您的情况下为6,这是解决方案。
  • 感谢 phimuemue。在我意识到它在做什么之前,我不得不阅读 unicornaddicts 代码几次。我删除了我的评论。
【解决方案2】:

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

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

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

【讨论】:

  • 我希望面试官意识到不是每个人都知道按位操作并且会接受这个答案,即使它占用更多空间。
【解决方案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);
}

为了乐趣和利润

编辑:

这个sn-p的解释。

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

【讨论】:

  • 我认为这里有一些错误。请检查数组:{ 2, 1, 2, 2, 1,1,5 } - DotNetFiddle 上的演示代码返回 6,而预期值应为 5
  • 这里没有错误。你的输入是错误的。你在这里有三倍而不是对:)
  • @aloisdg 你介意解释一下解决方案背后的理论吗?我已经厌倦了它并且它有效,但我想了解您如何知道对所有元素进行异或会导致未配对的 int。谢谢
  • @Anwuna 我添加了一个小sn-p。这背后的逻辑应该是自己出现的。
【解决方案4】:

最好的答案是 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];
}

【讨论】:

    【解决方案5】:

    对给定数组的所有元素执行异或操作

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

    【讨论】:

    • 它是如何解决问题的??你能试运行一个简单的例子吗? XOR 运算符如何用于查找没有对的元素。
    【解决方案6】:

    这是一个简单的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
    

    【讨论】:

    【解决方案7】:

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

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

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

    【讨论】:

      【解决方案8】:

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

      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]);
      

      【讨论】:

        【解决方案9】:

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

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

        【讨论】:

          【解决方案10】:

          上述问题的java解决方案:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-02-02
            • 2023-03-11
            • 2012-02-25
            • 1970-01-01
            • 2021-03-11
            • 2021-05-14
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多