Find a pair of elements from an array whose sum equals a given number

后端 未结 30 1069
暗喜
暗喜 2020-11-22 10:14

Given array of n integers and given a number X, find all the unique pairs of elements (a,b), whose summation is equal to X.

The following is my solution, it is O(nLo

30条回答
  •  盖世英雄少女心
    2020-11-22 10:59

    I can do it in O(n). Let me know when you want the answer. Note it involves simply traversing the array once with no sorting, etc... I should mention too that it exploits commutativity of addition and doesn't use hashes but wastes memory.


    using System; using System.Collections.Generic;

    /* An O(n) approach exists by using a lookup table. The approach is to store the value in a "bin" that can easily be looked up(e.g., O(1)) if it is a candidate for an appropriate sum.

    e.g.,

    for each a[k] in the array we simply put the it in another array at the location x - a[k].

    Suppose we have [0, 1, 5, 3, 6, 9, 8, 7] and x = 9

    We create a new array,

    indexes value

    9 - 0 = 9     0
    9 - 1 = 8     1
    9 - 5 = 4     5
    9 - 3 = 6     3
    9 - 6 = 3     6
    9 - 9 = 0     9
    9 - 8 = 1     8
    9 - 7 = 2     7
    

    THEN the only values that matter are the ones who have an index into the new table.

    So, say when we reach 9 or equal we see if our new array has the index 9 - 9 = 0. Since it does we know that all the values it contains will add to 9. (note in this cause it's obvious there is only 1 possible one but it might have multiple index values in it which we need to store).

    So effectively what we end up doing is only having to move through the array once. Because addition is commutative we will end up with all the possible results.

    For example, when we get to 6 we get the index into our new table as 9 - 6 = 3. Since the table contains that index value we know the values.

    This is essentially trading off speed for memory. */

    namespace sum
    {
        class Program
        {
            static void Main(string[] args)
            {
                int num = 25;
                int X = 10;
                var arr = new List();
                for(int i = 0; i <= num; i++) arr.Add((new Random((int)(DateTime.Now.Ticks + i*num))).Next(0, num*2));
                Console.Write("["); for (int i = 0; i < num - 1; i++) Console.Write(arr[i] + ", "); Console.WriteLine(arr[arr.Count-1] + "] - " + X);
                var arrbrute = new List>();
                var arrfast = new List>();
    
                for(int i = 0; i < num; i++)
                for(int j = i+1; j < num; j++)
                    if (arr[i] + arr[j] == X) 
                        arrbrute.Add(new Tuple(arr[i], arr[j]));
    
    
    
    
                int M = 500;
                var lookup = new List>();
                for(int i = 0; i < 1000; i++) lookup.Add(new List());
                for(int i = 0; i < num; i++)        
                {
                    // Check and see if we have any "matches"
                    if (lookup[M + X - arr[i]].Count != 0)
                    {
                        foreach(var j in lookup[M + X - arr[i]])
                        arrfast.Add(new Tuple(arr[i], arr[j])); 
                    }
    
                    lookup[M + arr[i]].Add(i);
    
                }
    
                for(int i = 0; i < arrbrute.Count; i++)
                    Console.WriteLine(arrbrute[i].Item1 + " + " + arrbrute[i].Item2 + " = " + X);
                Console.WriteLine("---------");
                for(int i = 0; i < arrfast.Count; i++)
                    Console.WriteLine(arrfast[i].Item1 + " + " + arrfast[i].Item2 + " = " + X);
    
                Console.ReadKey();
            }
        }
    }
    

提交回复
热议问题