2

I just had an online coding interview and one of the questions asked there is for a given array of integers, find out the number of pairs whose summation is equal to a certain number (passed as parameter inside the method ). For example an array is given as,

int[] a = {3, 2, 1, 45, 27, 6, 78, 9, 0};
int k = 9; // given number

So, there will be 2 pairs (3, 6) and (9, 0) whose sum is equal to 9. It's good to mention that how the pairs are formed doesn't matter. The means (3,6) and (6,3) will be considered as same pair. I provided the following solution (in Java) and curious to know if I missed any edge cases?

public static int numberOfPairs(int[] a, int k ){

    int len = a.length;

    if (len == 0){
      return -1;
    }

    Arrays.sort(a);
    int count  = 0, left = 0, right = len -1; 

    while( left < right ){

        if ( a[left] + a[right] == k  ){

            count++; 

            if (a[left] == a[left+1] && left < len-1 ){
              left++;
            }

            if ( a[right] == a[right-1] && right >1 ){
              right-- ; 
            }

            right--; // right-- or left++, otherwise, will get struck in the while loop 
        }

        else if ( a[left] + a[right] < k ){
          left++;
        }

        else {
          right--;
        }
    }

    return count; 
}

Besides, can anyone propose any alternative solution of the problem ? Thanks.

user2314737
  • 24,359
  • 17
  • 91
  • 104
Monica Hübner
  • 269
  • 1
  • 3
  • 16
  • 1
    Duplicate elements might be a problem e.g. {3, 3, 2,1,45, 27, 6, 78, 9, 0 } – ligi Nov 23 '15 at 01:35
  • I thought about that and provided 2 conditions if the k matches with the pair. if (a[left] == a[left+1] && left < len-1 ){ left++; } if ( a[right] == a[right-1] && right >1 ){ right-- ; } But, you give me thought, it may be possible more than 2 numbers are duplicate, say, int [] a = {3, 3, 2,2,2,2, 1,45, 27, 6, 78, 9, 0 }, here I have four 2's. May be I should use while again like this, while (a[left] == a[left+1] && left < len-1 ){ left++; } // same for right side as well – Monica Hübner Nov 23 '15 at 01:42
  • Possible duplicate of [Find a pair of elements from an array whose sum equals a given number](https://stackoverflow.com/questions/4720271/find-a-pair-of-elements-from-an-array-whose-sum-equals-a-given-number) – user2314737 Dec 31 '17 at 11:07

5 Answers5

9

Following solution will return the number of unique pairs

public static int numberOfPairs(Integer[] array, int sum) {
    Set<Integer> set = new HashSet<>(Arrays.asList(array));

    // this set will keep track of the unique pairs.
    Set<String> uniquePairs = new HashSet<String>();

    for (int i : array) {
        int x = sum - i;
        if (set.contains(x)) {
            int[] y = new int[] { x, i };
            Arrays.sort(y);
            uniquePairs.add(Arrays.toString(y));
        }
    }

    //System.out.println(uniquePairs.size());
    return uniquePairs.size();
}

The time complexity will be O(n).

Hope this helps.

tharindu_DG
  • 8,182
  • 5
  • 51
  • 58
  • You should use Set instead of Map. – WW. Nov 23 '15 at 01:40
  • Thanks for the suggestion @WW. – tharindu_DG Nov 23 '15 at 01:45
  • Set is better way of doing. Do you think your solution will work if there are more than 2 instances of same number ( I mention pairCount/2 part ) ? – Monica Hübner Nov 23 '15 at 02:04
  • @MonicaHübner : Yeah. It was a bug. Thank you for pointing out. I fixed it now. Please check. – tharindu_DG Nov 23 '15 at 02:13
  • This solution does not work with duplicates. For the example array of `[1, 2, 1, 2, 1, 2]` and `k = 3`, the number of pairs should be 9. Your solution returns 1. I realize your solution mentions a comment saying `unique pairs`, however the question does not specify that the elements are unique. – follmer May 23 '21 at 06:33
1

You can use the HashMap<K,V> where K: a[i] and V: k-a[i] This may result in an incorrect answer if there are duplicates in an array.

Say for instances:

int a[] = {4, 4, 4, 4, 4, 4, 4, 4, 4}

where k = 8 or:

int a[] = {1, 3, 3, 3, 3, 1, 2, 1, 2}

where k = 4.

So in order to avoid that, we can have a List<List<Integer>> , which can check each pair and see if it is already in the list.

static int numberOfPairs(int[] a, int k)
{
    List<List<Integer>> res = new ArrayList<>();
    Map<Integer, Integer> map = new HashMap<>();
    for(int element:a)
    {
        List<Integer> list = new ArrayList<>();
        if(map.containsKey(element))
        {
            list.add(element);
            list.add(map.get(element));
            if(!res.contains(list))
                res.add(list);
        }
        else
            map.put(k - element, element);        
    }
    return res.size();
}
p_flame
  • 92
  • 6
0

Your solution is overly complex, you can do this exercise in a much easier manner:

public static int numberOfPairs(int[] a, int k ){

    int count=0;
    List<Integer> dedup = new ArrayList<>(new HashSet<>(Arrays.asList(a)));
    for (int x=0 ; x < dedup.size() ; x++ ){
        for (int y=x+1 ; y < dedup.size() ; y++ ){
            if (dedup.get(x)+dedup.get(y) == k)
                count++;
        }
    }

    return count;
}

The trick here is to have a loop starting after the first loop's index to not count the same values twice, and not compare it with your own index. Also, you can deduplicate the array to avoid duplicate pairs, since they don't matter.

You can also sort the list, then break the loop as soon as your sum goes above k, but that's optimization.

Guillaume F.
  • 5,169
  • 1
  • 29
  • 54
0

This code will give you count of the pairs that equals to given sum and as well as the pair of elements that equals to sum

 private void pairofArrayElementsEqualstoGivenSum(int sum,Integer[] arr){
        int count=0;
        List numList = Arrays.asList(arr);
        for (int i = 0; i < arr.length; i++) {
            int num = sum - arr[i];
            if (numList.contains(num)) {
                count++;
                System.out.println("" + arr[i] + " " + num + " = "+sum);
            }
        }
        System.out.println("Total count of pairs "+count);
    }
viveksuggu
  • 599
  • 1
  • 6
  • 11
-1

Given an array of integers and a target value, determine the number of pairs of array elements with a difference equal to a target value. The function has the following parameters:

k: an integer, the target difference

arr: an array of integers

Using LINQ this is nice solution:

    public static int CountNumberOfPairsWithDiff(int k, int[] arr)
    {
        var numbers = arr.Select((value) => new { value });
        var pairs = from num1 in numbers
                    join num2 in numbers
                    on num1.value - k equals num2.value
                    select new[]
                {
                    num1.value, // first number in the pair
                    num2.value, // second number in the pair
                };
        foreach (var pair in pairs)
        {
            Console.WriteLine("Pair found: " + pair[0] + ", " + pair[1]);
        }

        return pairs.Count();
    }
Gunnar Siréus
  • 112
  • 1
  • 5