Search code examples
c#generic-collections

Find numbers in List<int> with specified difference


For a given a space separated list of numbers, what is the most effecient way of counting the total pairs of numbers which have a difference of N.

e.g. command line in put would be:

5 2

where 5 is the count of numbers to follow and 2 is the difference required

1 5 3 4 2

the 5 numbers to be considered

Output should be 3 because (5,3), (4,2) and (3,1) all have a diff of 2

I can get this algorithm to work, but is there a more efficient way of doing this if you have large sets of numbers to work with? I have incluced three comparison options and the second one should be better than the third but is there something I'm forgetting which could make it much quicker?

private static void Difference()
{
    string[] firstInput = SplitInput(Console.ReadLine());

    int numberOfNumbers = int.Parse(firstInput[0]);
    int diffOfNumbers = int.Parse(firstInput[1]);

    string[] secondInput = SplitInput(Console.ReadLine());

    List<int> numbers = secondInput.Select(x => Int32.Parse(x)).ToList();

    int possibleCombinations = 0;

    // Option 1
    foreach (int firstNumber in numbers)
    {
        List<int> compareTo = numbers.GetRange(numbers.IndexOf(firstNumber) + 1, numbers.Count - numbers.IndexOf(firstNumber) - 1);

        foreach (int secondNumber in compareTo)
        {
            int diff = firstNumber - secondNumber;

            if (Math.Abs(diff) == diffOfNumbers)
            {
                possibleCombinations++;
            }
        }
    }

    // Option 2
    foreach (int firstNumber in numbers)
    {
        if (numbers.Contains(firstNumber + diffOfNumbers))
        {
                possibleCombinations++;
        }
    }

    // Option 3
    foreach (int firstNumber in numbers)
    {
        foreach (int secondNumber in numbers)
        {
            int diff = firstNumber - secondNumber;

            if(Math.Abs(diff) == diffOfNumbers)
            {
                possibleOptions++;
            }
        }
    }

    Console.WriteLine(string.Format("Possible number of options are: {0}", possibleCombinations));
    Console.ReadLine();
}

private static string[] SplitInput(string input)
{
    return input.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
}

Solution

  • If duplicate numbers are not allowed or to be ignored (only count unique pairs), you could use a HashSet<int>:

    HashSet<int> myHashSet = ...
    int difference = ...
    int count;
    foreach (int number in myHashSet)
    {
        int counterpart = number - difference;
        if (myHashSet.Contains(counterpart))
        {
            count++;
        }
    }