Distinguishing extra element from two arrays?

后端 未结 19 584
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-28 09:45

One of my friend was asked this question in an interview -

  • You have given two integer arrays each of size 10.
  • Both contains 9 equal elements (say 1 t
相关标签:
19条回答
  • 2020-12-28 10:27

    How about getting the total sum for each of the arrays and subtracting one from the other? The difference is the extra element.

    eg: A = 1,2,3,4,5 B = 1,2,3,4

    sum(A) = 15, sum(B) = 10; 15 - 10 = 5 which is the extra element.

    0 讨论(0)
  • 2020-12-28 10:28

    Heres a solution that doesn't require hash or set, O(1) space and O(n) time. Its not the most optimal solution posted but its a good one. All you do is sum the values in list1 and sum the values list2 and find the difference.

    Javascript

    var findExtra= function (l1, l2) {
        var l1_sum = l1.reduce(function(prev, curr) {
            return prev + curr;
        });
        var l2_sum = l2.reduce(function(prev, curr) {
            return prev + curr;
        });
    
        console.log(l1_sum, l2_sum);
    
        if (l1.length < l2.length) return l2_sum - l1_sum;
        return l1_sum - l2_sum;
    }
    
    console.log(findExtra([1,2,3,4,-1], [1,2,3,4]));
    
    0 讨论(0)
  • 2020-12-28 10:29

    If you need this to scale, then I would use one of the many Set implementations in the world. For example, Java's HashSet.

    Throw all of the first array in the Set. Then, for each member of the second array, if it is contained in the Set, remove it; otherwise mark it as Unique #2. After this procedure, the last remaining member of the Set is Unique #1.

    I'd probably do it this way, even on an interview, and even for simple ten-element arrays. Life is too short to spend trying to find the clever way to scale a wall when there's a perfectly good door in it.

    0 讨论(0)
  • 2020-12-28 10:29

    This can be done using Xor.

    First Xor all elements from both arrays. Let x and y be the extra element each array. What remains is x^y.

    Now in xor, if a bit is set, it means that it is set in one of the the two numbers and not in the other one.

    We can use this to find the missing indivdual numbers. So find a bit which is set in a^b. Getting Righmost bit is easy. It can be done by

    n& ~(n-1)

    (1110) & ~(1101) = 0010

    To get each of the individual numbers, we split the numbers of both the arrays into 2 parts, numbers have the checked bit set, and which don't.We do XOR on each of the set, so that we get the values a and b. This cancels out all the repeating elements, and separates out x and y.

    This can be quite confusing. Now take x=3, y = 2

    x=110

    y=010

    x^y=100

    So when we get the bit set, the number we get is bitset = 100. Third bit is set. Suppose array elements be 5,1 ( Both repeated twice)

    5=101

    6=001

    What now, 5 has 3rd bit, so we xor it with x

    we get x^5^5 = x

    Similarly, 6 doesn't have 3rd bit set, so xor with y.

    We get y^1^1 = y

    Code

    for(i=0;i<n;i++)
    xor = xor^a[i]^b[i];
    
    set_bit = xor & ~(xor-1) ;
    for(i = 0; i < n; i++)
    {
    if(a[i] & set_bit_no)
     x = x ^ a[i]; /*XOR of first set */
    else
     y = y ^ a[i]; /*XOR of second set*/
    
    if(b[i] & set_bit_no)
     x = x ^ b[i]; /*XOR of first set */
    else
     y = y ^ b[i]; /*XOR of second set*/
     }
    

    This is similar to the method posted here http://www.geeksforgeeks.org/find-two-non-repeating-elements-in-an-array-of-repeating-elements/

    0 讨论(0)
  • 2020-12-28 10:29

    Here's some simple pseudocode for a solution. I'm assuming it's OK to modify the arrays and that arrays have a remove(value) method (or that you could write one trivially). It takes the 2 arrays and returns an array containg 2 values, the first is the unique value from the first array and the second is the unique value from the 2nd array.

    function findUnique(a:Array, b:Array):Array {
      var uniqueFromA:int;
      var uniqueFromB:int;
    
      for each(value:int in a) {
        var len:int = b.length;
        b.remove(value);
        /* b's length didn't change, so nothing was removed, so the value doesn't
         * exist in it. */
        if(b.length == len) {
          uniqueFromA = value;
        }
      }
    
      /* Only the unique value in b still exists in b */
      uniqueFromB = b[0];
    
      return [uniqueFromA, uniqueFromB];
    }
    
    0 讨论(0)
  • 2020-12-28 10:30
    • You have given two integer arrays each of size 10.
    • Both contains 9 equal elements (say 1 to 9)
    • Only one element is different.

    Depending on the constraints, you can solve this very quickly in linear time. If you hold an int[10], then you can assume that an element at index 1 corresponds to the number 1; the element itself holds a count of both arrays. The following pseudocode will solve the problem quickly:

    let buckets = new int[10] // init all buckets to zero
    for num in arr1 do buckets[num]++ // add numbers from the first array
    for num in arr2 do buckets[num]++ // add from the second array
    for i in 1 to 9 do                // find odd man out
        if buckets[i] <= 1 then return i
    

    This is essentially a bounded hashtable. This only works if our given list of elements is constrained between 1 and 9.

    Technically, you don't even need to keep a running count of each element. You could, in principle, simply loop through arr1, then iterate through arr2 until you run across an element which was not hashed from the first array.

    0 讨论(0)
提交回复
热议问题