133

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(nLog(n)+n), but I am not sure whether or not it is optimal.

int main(void)
{
    int arr [10] = {1,2,3,4,5,6,7,8,9,0};
    findpair(arr, 10, 7);
}
void findpair(int arr[], int len, int sum)
{
    std::sort(arr, arr+len);
    int i = 0;
    int j = len -1;
    while( i < j){
        while((arr[i] + arr[j]) <= sum && i < j)
        {
            if((arr[i] + arr[j]) == sum)
                cout << "(" << arr[i] << "," << arr[j] << ")" << endl;
            i++;
        }
        j--;
        while((arr[i] + arr[j]) >= sum && i < j)
        {
            if((arr[i] + arr[j]) == sum)
                cout << "(" << arr[i] << "," << arr[j] << ")" << endl;
            j--;
        }
    }
}
Tot Zam
  • 7,839
  • 9
  • 49
  • 72
Gin
  • 1,763
  • 3
  • 12
  • 17
  • 3
    An O(n) solution is possible if you chuck everything into an O(1) set of some kind instead of sorting the array. – Anon. Jan 18 '11 at 03:46
  • 1
    @Anon Can u tell more details, how to build such a set? – Gin Jan 18 '11 at 03:57
  • 3
    Use hashes. Most languages will have an amortized O(1) HashSet somewhere in their standard libraries. – Anon. Jan 18 '11 at 03:59
  • 15
    A minor nit - O(nLog(n)+n) is O(nLog(n)). Big O notation retains only the dominant term and drops all lower order terms. – pjs Jun 01 '13 at 14:40
  • 2
    Note short circuit evaluation and off-by-one addressing: `while((arr[i] + arr[j]) <= sum && i < j)` should be `while( i < J && arr[i] + arr[j] <= sum )`. (similar for the second subloop) – wildplasser Aug 10 '13 at 12:40
  • I have a doubt.In the second loop why didn't you add i++ at last as you added j-- in the first case.Just asking whether you forgot or it shouldn't be . I have no clue of why it shouldn't be – user2221214 Aug 14 '14 at 19:48
  • @Gin I think the decrement of index j between the 2 while loops is redundant - did you add that as an optimization? – Electrix Oct 22 '15 at 01:27
  • values.Where(x => values.Contains(sum - x)).Select(x=> new{x,y=sum-x}); – Ali Bayat Aug 03 '18 at 03:09
  • Voting to reopen as 1) the question is pretty popular 2) it is linked as an answer in other questions. The "Closed" status gives a false impression that the question is useless. – Déjà vu Jul 14 '20 at 07:21

32 Answers32

192

There are 3 approaches to this solution:

Let the sum be T and n be the size of array

Approach 1:
The naive way to do this would be to check all combinations (n choose 2). This exhaustive search is O(n2).

Approach 2: 
 A better way would be to sort the array. This takes O(n log n)
Then for each x in array A, use binary search to look for T-x. This will take O(nlogn).
So, overall search is  O(n log n)

Approach 3 :
The best way would be to insert every element into a hash table (without sorting). This takes O(n) as constant time insertion.
Then for every x, we can just look up its complement, T-x, which is O(1).
Overall the run time of this approach is O(n).


You can refer more here.Thanks.


kinshuk4
  • 3,181
  • 3
  • 31
  • 40
  • How would you create hash table for the elements of the array? – Satish Patel Dec 19 '13 at 16:13
  • Refer the link I have shared. We can have a parallel array to store the element as the index, or you can add the elements to the hashtable and use contains on them. Sorry for such a late reply. – kinshuk4 Mar 23 '14 at 22:55
  • 11
    You might get a false positive if there is an element that is exactly half the target sum. – Florian F Sep 25 '14 at 15:43
  • The time complexity notation hides the fact that approach 1 is actually `1/2 n(n-1)` and approach 2 is actually `2 n logn`, so it may not be always more efficient. – SOFe Sep 03 '16 at 15:04
  • I agree with you @PEMapModder and that's why I have used O notation :). – kinshuk4 Sep 16 '16 at 17:01
  • 2
    @Florian_F Can't you just special case where you have an element that is exactly half? – Joseph Garvin Mar 18 '17 at 23:49
  • do you mean set , by hash table in approach 3 : ```The best way would be to insert every element into a hash table (without sorting). This takes O(n) as constant time insertion.``` then we have to divide it by 2 ( integer division) to get the no of pairs right? – lazarus Oct 06 '18 at 07:52
  • 1
    @jazzz I mean HashMap here, though HashSet will also do. Here is the implementation - https://github.com/kinshuk4/AlgorithmUtil/blob/master/src/com/vaani/algo/array/TwoSum.java. Hope it helps. – kinshuk4 Oct 06 '18 at 16:27
  • take a look at [my solution](https://github.com/pcodex/cplusplus/tree/master/sumofpairs/sumofpairs) for Approach 3 above. Handles duplicates. – pcodex Dec 07 '18 at 15:30
  • is sorting in approach 2 used only to achieve a time complexity of O(n log n) , or does it affect the search process as well ? – Wesam Sep 12 '19 at 18:24
  • @Wesam Sorting takes O(n log n). Now we can do a binary search which takes O(log n). Binary search for n elements also takes O(n log n). – kinshuk4 Sep 13 '19 at 12:03
137
# Let arr be the given array.
# And K be the give sum


for i=0 to arr.length - 1 do
  # key is the element and value is its index.
  hash(arr[i]) = i  
end-for

for i=0 to arr.length - 1 do
  # if K-th element exists and it's different then we found a pair
  if hash(K - arr[i]) != i  
    print "pair i , hash(K - arr[i]) has sum K"
  end-if
end-for
hjpotter92
  • 75,209
  • 33
  • 136
  • 171
codaddict
  • 429,241
  • 80
  • 483
  • 523
  • 26
    You could even do it in one iteration through the array, by putting your if statement from the second loop, right after the hash assignment in the first loop. – Alexander Kondratskiy Jan 18 '11 at 16:06
  • 4
    Minor note: This (as well as Alexander's suggestion) will double-print some pairs, whether uniqueness of a pair is determined by index (as could be implied from this answer) or by value (as it seems in the OP). There could be quite a few (O(n^2)) unique pairs by index, e.g. `arr=[1,2,1,2,1,2,1,...]`. For uniqueness by value, it seems like another hash table keyed by a value-pair would do the trick. Still a nice, compact, elegant answer. +1 – William Feb 10 '11 at 18:49
  • 2
    @codaddict But what if array is very large ? I mean the range of values in it is very large ? So, the hash solution will be less practical then. Any alternate and optimal method for the same ? – Prashant Singh Oct 22 '12 at 15:14
  • 15
    What if there are duplicates? – zad Sep 11 '13 at 17:08
  • one question, array in php are already implemented in hash tables. Is it necessary to do that? I guess a simple in_array would work with the same complexity. – David 天宇 Wong May 10 '14 at 13:26
  • 1
    To me this [video](https://www.youtube.com/watch?v=XKu_SEDAykw) by [Life at Google](https://www.youtube.com/channel/UCWIzrKzN4KY6BPU8hsk880Q) youtube channel seems to be showing it a little wrong. Instead of searching for the complement in the hash-set, they are looking for the value itself, which is kind of wrong. Am I right? – Sнаđошƒаӽ Jan 26 '17 at 14:56
  • 2
    Does `hash(K - arr[i]) != i` somehow check both presence and the lack of a match? I'd expect there to be a separate check for presence. – Joseph Garvin Mar 19 '17 at 20:35
  • 1
    @AlexanderKondratskiy Say the target is 8 and 4 occurs twice in the sequence. Assume we do as you suggest and put the if right after the assignment. The first time we encounter 4 the `!=` will prevent matching which is fine. The second time we encounter 4 since you suggest putting the assignment first we will blow away the earlier 4 index value, and then the check will fail a second time (incorrectly). So I think you actually want the assignment to come after the if. – Joseph Garvin Mar 19 '17 at 20:42
  • what is hash() here? is it an array , or a built in hash function of any language? – lazarus Oct 06 '18 at 03:51
  • 1
    how does `if hash(K - arr[i]) != i // if K - ele exists ` ensure that K-arr[i] exists? It just proves that it is not at index i – pcodex Dec 07 '18 at 14:06
67

Implementation in Java : Using codaddict's algorithm (Maybe slightly different)

import java.util.HashMap;

public class ArrayPairSum {


public static void main(String[] args) {        

    int []a = {2,45,7,3,5,1,8,9};
    printSumPairs(a,10);        

}


public static void printSumPairs(int []input, int k){
    Map<Integer, Integer> pairs = new HashMap<Integer, Integer>();

    for(int i=0;i<input.length;i++){

        if(pairs.containsKey(input[i]))
            System.out.println(input[i] +", "+ pairs.get(input[i]));
        else
            pairs.put(k-input[i], input[i]);
    }

}
}

For input = {2,45,7,3,5,1,8,9} and if Sum is 10

Output pairs:

3,7 
8,2
9,1

Some notes about the solution :

  • We iterate only once through the array --> O(n) time
  • Insertion and lookup time in Hash is O(1).
  • Overall time is O(n), although it uses extra space in terms of hash.
Rambo7
  • 1,135
  • 10
  • 17
  • 1
    This is good ONLY if the input array has not duplicates. – Naren Mar 06 '15 at 22:10
  • 2
    @Naren: It makes no difference even if there are duplicates in the given array – randomcompiler Mar 12 '15 at 16:42
  • The above link has hashmap related explanation as a naive approach which looks different from the solution explained above. Can anyone explain above solution? – John Oct 22 '15 at 06:28
  • 1
    it does not implement what codaddicts wrote, and what you did, though it works, is unnecessary complicated. It is meaningless to `put(k-input[i], input[i])` (codaddicts puts the index as value which is useful.) What you wrote can be simplified to `for (i:input){ if (intSet.contains(sum-i) { print(i + "," + (sum-i) ); } else {intSet.add(i)}` – Adrian Shum Oct 22 '15 at 07:11
  • 1
    Okay, Thanks. For other people reference purpose,I just created another thread so that who are having difficulty in analyzing how this solution works can understand it properly. Here is the link : http://stackoverflow.com/questions/33274952/understanding-pair-of-sum-and-codaddicts-algorithm – John Oct 22 '15 at 07:24
  • @AdrianShum So, you meant to say, it's not a codaddicts algorithm? Can you point me to where is that algorithm available online to read? – John Oct 22 '15 at 07:25
  • Just scroll up. The accepted answer is by "codaddict" (http://stackoverflow.com/a/4720397/395202) . It is not actually some kind of publicly useful "algorithm" – Adrian Shum Oct 22 '15 at 07:40
  • This can be improved to work in duplicate scenario also as below. static int noOfPairsNew(int [] a, long k){ Set nos = new HashSet<>(); HashSet uniq = new HashSet<>(); for (int num : a){ if (nos.contains(num)){ uniq.add(num); }else { nos.add((int)k - num); } } return uniq.size(); } – Udara S.S Liyanage Apr 13 '18 at 02:42
8

Solution in java. You can add all the String elements to an ArrayList of strings and return the list. Here I am just printing it out.

void numberPairsForSum(int[] array, int sum) {
    HashSet<Integer> set = new HashSet<Integer>();
    for (int num : array) {
        if (set.contains(sum - num)) {
            String s = num + ", " + (sum - num) + " add up to " + sum;
            System.out.println(s);
        }
        set.add(num);
    }
}
Vikram Dave
  • 136
  • 1
  • 6
4

Python Implementation:

import itertools
list = [1, 1, 2, 3, 4, 5,]
uniquelist = set(list)
targetsum = 5
for n in itertools.combinations(uniquelist, 2):
    if n[0] + n[1] == targetsum:
        print str(n[0]) + " + " + str(n[1])

Output:

1 + 4
2 + 3
Erict2k
  • 15
  • 4
ASKN
  • 356
  • 2
  • 10
  • 2
    look in ... will be overhead for searching element – Nikhil Rupanawar Jun 10 '14 at 18:27
  • this works with non unique elements: import itertools list = [1, 1, 2, 3, 4, 5,] targetsum = 5 for n in itertools.combinations(list, 2): if n[0] + n[1] == targetsum: print str(n[0]) + " + " + str(n[1]) – Cris Nov 30 '20 at 04:34
4

C++11, run time complexity O(n):

#include <vector>
#include <unordered_map>
#include <utility>

std::vector<std::pair<int, int>> FindPairsForSum(
        const std::vector<int>& data, const int& sum)
{
    std::unordered_map<int, size_t> umap;
    std::vector<std::pair<int, int>> result;
    for (size_t i = 0; i < data.size(); ++i)
    {
        if (0 < umap.count(sum - data[i]))
        {
            size_t j = umap[sum - data[i]];
            result.push_back({data[i], data[j]});
        }
        else
        {
            umap[data[i]] = i;
        }
    }

    return result;
}
iamantony
  • 1,290
  • 17
  • 31
3

Here is a solution witch takes into account duplicate entries. It is written in javascript and assumes array is sorted. The solution runs in O(n) time and does not use any extra memory aside from variable.

var count_pairs = function(_arr,x) {
  if(!x) x = 0;
  var pairs = 0;
  var i = 0;
  var k = _arr.length-1;
  if((k+1)<2) return pairs;
  var halfX = x/2; 
  while(i<k) {
    var curK = _arr[k];
    var curI = _arr[i];
    var pairsThisLoop = 0;
    if(curK+curI==x) {
      // if midpoint and equal find combinations
      if(curK==curI) {
        var comb = 1;
        while(--k>=i) pairs+=(comb++);
        break;
      }
      // count pair and k duplicates
      pairsThisLoop++;
      while(_arr[--k]==curK) pairsThisLoop++;
      // add k side pairs to running total for every i side pair found
      pairs+=pairsThisLoop;
      while(_arr[++i]==curI) pairs+=pairsThisLoop;
    } else {
      // if we are at a mid point
      if(curK==curI) break;
      var distK = Math.abs(halfX-curK);
      var distI = Math.abs(halfX-curI);
      if(distI > distK) while(_arr[++i]==curI);
      else while(_arr[--k]==curK);
    }
  }
  return pairs;
}

I solved this during an interview for a large corporation. They took it but not me. So here it is for everyone.

Start at both side of the array and slowly work your way inwards making sure to count duplicates if they exist.

It only counts pairs but can be reworked to

  • find the pairs
  • find pairs < x
  • find pairs > x

Enjoy!

Drone Brain
  • 399
  • 2
  • 8
3

O(n)

def find_pairs(L,sum):
    s = set(L)
    edgeCase = sum/2
    if L.count(edgeCase) ==2:
        print edgeCase, edgeCase
    s.remove(edgeCase)      
    for i in s:
        diff = sum-i
        if diff in s: 
            print i, diff


L = [2,45,7,3,5,1,8,9]
sum = 10          
find_pairs(L,sum)

Methodology: a + b = c, so instead of looking for (a,b) we look for a = c - b

garg10may
  • 5,128
  • 8
  • 42
  • 78
2

Just attended this question on HackerRank and here's my 'Objective C' Solution:

-(NSNumber*)sum:(NSArray*) a andK:(NSNumber*)k {
    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
    long long count = 0;
    for(long i=0;i<a.count;i++){

        if(dict[a[i]]) {
            count++;
            NSLog(@"a[i]: %@, dict[array[i]]: %@", a[i], dict[a[i]]);
        }
        else{
            NSNumber *calcNum = @(k.longLongValue-((NSNumber*)a[i]).longLongValue);
            dict[calcNum] = a[i];
        }

    }
    return @(count);
}

Hope it helps someone.

Saru
  • 863
  • 1
  • 14
  • 22
2

Implementation in Java : Using codaddict's algorithm:

import java.util.Hashtable;
public class Range {

public static void main(String[] args) {
    // TODO Auto-generated method stub
    Hashtable mapping = new Hashtable();
    int a[]= {80,79,82,81,84,83,85};
    int k = 160;

    for (int i=0; i < a.length; i++){
        mapping.put(a[i], i);
    }

    for (int i=0; i < a.length; i++){
        if (mapping.containsKey(k - a[i]) && (Integer)mapping.get(k-a[i]) != i){
            System.out.println(k-a[i]+", "+ a[i]);
        }
    }      

}

}

Output:

81, 79
79, 81

If you want duplicate pairs (eg: 80,80) also then just remove && (Integer)mapping.get(k-a[i]) != i from the if condition and you are good to go.

Arpit Agarwal
  • 537
  • 1
  • 5
  • 17
  • for C# this may be work - int k = 16; int count = 0; int[] intArray = { 5, 7, 11, 23,8,9,15,1,10,6 }; for (int i = 0; i < intArray.Length; i++) { for (int j = i; j < intArray.Length; j++) { if ((k - intArray[i]) == intArray[j]) { count++; } } } Console.WriteLine(count); – MukulSharma Jan 18 '17 at 11:26
1

this is the implementation of O(n*lg n) using binary search implementation inside a loop.

#include <iostream>

using namespace std;

bool *inMemory;


int pairSum(int arr[], int n, int k)
{
    int count = 0;

    if(n==0)
        return count;
    for (int i = 0; i < n; ++i)
    {
        int start = 0;
        int end = n-1;      
        while(start <= end)
        {
            int mid = start + (end-start)/2;
            if(i == mid)
                break;
            else if((arr[i] + arr[mid]) == k && !inMemory[i] && !inMemory[mid])
            {
                count++;
                inMemory[i] = true;
                inMemory[mid] = true;
            }
            else if(arr[i] + arr[mid] >= k)
            {
                end = mid-1;
            }
            else
                start = mid+1;
        }
    }
    return count;
}


int main()
{
    int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    inMemory = new bool[10];
    for (int i = 0; i < 10; ++i)
    {
        inMemory[i] = false;
    }
    cout << pairSum(arr, 10, 11) << endl;
    return 0;
}
Lokesh Basu
  • 41
  • 3
  • 8
1

In python

arr = [1, 2, 4, 6, 10]
diff_hash = {}
expected_sum = 3
for i in arr:
    if diff_hash.has_key(i):
        print i, diff_hash[i]
    key = expected_sum - i
    diff_hash[key] = i
Nikhil Rupanawar
  • 3,771
  • 9
  • 32
  • 49
1

Nice solution from Codeaddict. I took the liberty of implementing a version of it in Ruby:

def find_sum(arr,sum)
 result ={}
 h = Hash[arr.map {|i| [i,i]}]
 arr.each { |l| result[l] = sum-l  if h[sum-l] && !result[sum-l]  }
 result
end

To allow duplicate pairs (1,5), (5,1) we just have to remove the && !result[sum-l] instruction

obaqueiro
  • 942
  • 12
  • 29
1

Here is Java code for three approaches:
1. Using Map O(n), HashSet can also be used here.
2. Sort array and then use BinarySearch to look for complement O(nLog(n))
3. Traditional BruteForce two loops O(n^2)

public class PairsEqualToSum {

public static void main(String[] args) {
    int a[] = {1,10,5,8,2,12,6,4};
    findPairs1(a,10);
    findPairs2(a,10);
    findPairs3(a,10);

}


//Method1 - O(N) use a Map to insert values as keys & check for number's complement in map
    static void findPairs1(int[]a, int sum){
        Map<Integer, Integer> pairs = new HashMap<Integer, Integer>();
        for(int i=0; i<a.length; i++){
            if(pairs.containsKey(sum-a[i]))
                System.out.println("("+a[i]+","+(sum-a[i])+")");
            else
               pairs.put(a[i], 0);
        }
    }



//Method2 - O(nlog(n)) using Sort
static void findPairs2(int[]a, int sum){
        Arrays.sort(a);
        for(int i=0; i<a.length/2; i++){
            int complement = sum - a[i];
            int foundAtIndex = Arrays.binarySearch(a,complement);
            if(foundAtIndex >0 && foundAtIndex != i) //to avoid situation where binarySearch would find the original and not the complement like "5"
                System.out.println("("+a[i]+","+(sum-a[i])+")");
        }
 }

//Method 3 - Brute Force O(n^2)
static void findPairs3(int[]a, int sum){

    for(int i=0; i<a.length; i++){
        for(int j=i; j<a.length;j++){
            if(a[i]+a[j] == sum)
                System.out.println("("+a[i]+","+a[j]+")");
        }
    }
}

}
user1529412
  • 3,386
  • 7
  • 24
  • 41
1

A Simple program in java for arrays having unique elements:

import java.util.*;
public class ArrayPairSum {
    public static void main(String[] args) { 
        int []a = {2,4,7,3,5,1,8,9,5};
        sumPairs(a,10);  
    }

    public static void sumPairs(int []input, int k){
      Set<Integer> set = new HashSet<Integer>();    
      for(int i=0;i<input.length;i++){

        if(set.contains(input[i]))
            System.out.println(input[i] +", "+(k-input[i]));
        else
            set.add(k-input[i]);
       }
    }
}
Pankaj Jaiswal
  • 593
  • 7
  • 15
1

A simple Java code snippet for printing the pairs below:

    public static void count_all_pairs_with_given_sum(int arr[], int S){
        if(arr.length < 2){
        return;
    }        
    HashSet values = new HashSet(arr.length);
    for(int value : arr)values.add(value);
    for(int value : arr){
        int difference = S - value;
    if(values.contains(difference) && value<difference){
        System.out.printf("(%d, %d) %n", value, difference);
        }
    }
    }
karthikbv
  • 193
  • 1
  • 4
  • 13
1

Another solution in Swift: the idea is to create an hash that store values of (sum - currentValue) and compare this to the current value of the loop. The complexity is O(n).

func findPair(list: [Int], _ sum: Int) -> [(Int, Int)]? {
    var hash = Set<Int>() //save list of value of sum - item.
    var dictCount = [Int: Int]() //to avoid the case A*2 = sum where we have only one A in the array
    var foundKeys  = Set<Int>() //to avoid duplicated pair in the result.

    var result = [(Int, Int)]() //this is for the result.
    for item in list {

        //keep track of count of each element to avoid problem: [2, 3, 5], 10 -> result = (5,5)
        if (!dictCount.keys.contains(item)) {
            dictCount[item] = 1
        } else {
            dictCount[item] = dictCount[item]! + 1
        }

        //if my hash does not contain the (sum - item) value -> insert to hash.
        if !hash.contains(sum-item) {
            hash.insert(sum-item)
        }

        //check if current item is the same as another hash value or not, if yes, return the tuple.
        if hash.contains(item) &&
            (dictCount[item] > 1 || sum != item*2) // check if we have item*2 = sum or not.
        {
            if !foundKeys.contains(item) && !foundKeys.contains(sum-item) {
                foundKeys.insert(item) //add to found items in order to not to add duplicated pair.
                result.append((item, sum-item))
            }
        }
    }
    return result
}

//test:
let a = findPair([2,3,5,4,1,7,6,8,9,5,3,3,3,3,3,3,3,3,3], 14) //will return (8,6) and (9,5)
Duyen-Hoa
  • 14,854
  • 4
  • 32
  • 43
1

My Solution - Java - Without duplicates

    public static void printAllPairSum(int[] a, int x){
    System.out.printf("printAllPairSum(%s,%d)\n", Arrays.toString(a),x);
    if(a==null||a.length==0){
        return;
    }
    int length = a.length;
    Map<Integer,Integer> reverseMapOfArray = new HashMap<>(length,1.0f);
    for (int i = 0; i < length; i++) {
        reverseMapOfArray.put(a[i], i);
    }

    for (int i = 0; i < length; i++) {
        Integer j = reverseMapOfArray.get(x - a[i]);
        if(j!=null && i<j){
            System.out.printf("a[%d] + a[%d] = %d + %d = %d\n",i,j,a[i],a[j],x);
        }
    }
    System.out.println("------------------------------");
}
LiozM
  • 146
  • 7
0

This prints the pairs and avoids duplicates using bitwise manipulation.

public static void findSumHashMap(int[] arr, int key) {
    Map<Integer, Integer> valMap = new HashMap<Integer, Integer>();
    for(int i=0;i<arr.length;i++)
        valMap.put(arr[i], i);

    int indicesVisited = 0; 
    for(int i=0;i<arr.length;i++) {
        if(valMap.containsKey(key - arr[i]) && valMap.get(key - arr[i]) != i) {
            if(!((indicesVisited & ((1<<i) | (1<<valMap.get(key - arr[i])))) > 0)) {
                int diff = key-arr[i];
                System.out.println(arr[i] + " " +diff);
                indicesVisited = indicesVisited | (1<<i) | (1<<valMap.get(key - arr[i]));
            }
        }
    }
}
codewarrior
  • 964
  • 4
  • 18
  • 32
0

I bypassed the bit manuplation and just compared the index values. This is less than the loop iteration value (i in this case). This will not print the duplicate pairs and duplicate array elements also.

public static void findSumHashMap(int[] arr, int key) {
    Map<Integer, Integer> valMap = new HashMap<Integer, Integer>();
    for (int i = 0; i < arr.length; i++) {
        valMap.put(arr[i], i);
    }
    for (int i = 0; i < arr.length; i++) {
        if (valMap.containsKey(key - arr[i])
                && valMap.get(key - arr[i]) != i) {
            if (valMap.get(key - arr[i]) < i) {
                int diff = key - arr[i];
                System.out.println(arr[i] + " " + diff);
            }
        }
    }
}
blo0p3r
  • 6,642
  • 8
  • 49
  • 68
Surya
  • 1
0

in C#:

        int[] array = new int[] { 1, 5, 7, 2, 9, 8, 4, 3, 6 }; // given array
        int sum = 10; // given sum
        for (int i = 0; i <= array.Count() - 1; i++)
            if (array.Contains(sum - array[i]))
                Console.WriteLine("{0}, {1}", array[i], sum - array[i]);
Thomas
  • 2,713
  • 5
  • 30
  • 52
Chrishan
  • 126
  • 1
  • 3
0

One Solution can be this, but not optimul (The complexity of this code is O(n^2)):

public class FindPairsEqualToSum {

private static int inputSum = 0;

public static List<String> findPairsForSum(int[] inputArray, int sum) {
    List<String> list = new ArrayList<String>();
    List<Integer> inputList = new ArrayList<Integer>();
    for (int i : inputArray) {
        inputList.add(i);
    }
    for (int i : inputArray) {
        int tempInt = sum - i;
        if (inputList.contains(tempInt)) {
            String pair = String.valueOf(i + ", " + tempInt);
            list.add(pair);
        }
    }
    return list;
   }
}
Shridutt Kothari
  • 7,819
  • 4
  • 43
  • 61
0

A simple python version of the code that find a pair sum of zero and can be modify to find k:

def sumToK(lst):
    k = 0  # <- define the k here
    d = {} # build a dictionary 

# build the hashmap key = val of lst, value = i
for index, val in enumerate(lst):
    d[val] = index

# find the key; if a key is in the dict, and not the same index as the current key
for i, val in enumerate(lst):
    if (k-val) in d and d[k-val] != i:
        return True

return False

The run time complexity of the function is O(n) and Space: O(n) as well.

Billz
  • 7,571
  • 7
  • 32
  • 33
0
 public static int[] f (final int[] nums, int target) {
    int[] r = new int[2];
    r[0] = -1;
    r[1] = -1;
    int[] vIndex = new int[0Xfff];
    for (int i = 0; i < nums.length; i++) {
        int delta = 0Xff;
        int gapIndex = target - nums[i] + delta;
        if (vIndex[gapIndex] != 0) {
            r[0] = vIndex[gapIndex];
            r[1] = i + 1;
            return r;
        } else {
            vIndex[nums[i] + delta] = i + 1;
        }
    }
    return r;
}
Bruce Zu
  • 447
  • 4
  • 17
0

less than o(n) solution will be=>

function(array,k)
          var map = {};
          for element in array
             map(element) = true;
             if(map(k-element)) 
                 return {k,element}
Shishir Arora
  • 4,983
  • 3
  • 27
  • 34
0

Solution in Python using list comprehension

f= [[i,j] for i in list for j in list if j+i==X];

O(N2)

also gives two ordered pairs- (a,b) and (b,a) as well

Sнаđошƒаӽ
  • 15,289
  • 12
  • 72
  • 86
Ashwin Aravind
  • 181
  • 1
  • 7
  • You might mention a language, whether the pairs (a, b) and (b, a) are unique, and what question this answers (the question does not contain an explicit one - `I am not sure … Thanks for comments`). You might denote the stab at complexity closer to O(n²). – greybeard Aug 26 '16 at 16:24
0

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<int>();
            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<Tuple<int,int>>();
            var arrfast = new List<Tuple<int,int>>();

            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<int, int>(arr[i], arr[j]));




            int M = 500;
            var lookup = new List<List<int>>();
            for(int i = 0; i < 1000; i++) lookup.Add(new List<int>());
            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<int, int>(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();
        }
    }
}
Wesam
  • 864
  • 3
  • 15
  • 27
AbstractDissonance
  • 1
  • 2
  • 13
  • 31
  • Basically to avoid hashes we have to create a table that can accept random insertions at somewhat arbitrary indices. Hence I use M to make sure that there is enough elements and pre-allocate a contiguous set even though most will not be used. A hash set would take care of this directly. – AbstractDissonance Jan 18 '11 at 04:41
  • So, you're using a hash set with a simple hash function and size greater than the max value of your hash function? – Chris Hopman Jan 18 '11 at 05:59
  • Also may as well use the identity function for your hash function at this point. That is, put a[k] at the a[k]-th "bin". – Chris Hopman Jan 18 '11 at 06:02
  • Because a[k] and X - a[k] are used an indices and I'm using an array, it means that the minimum index cannot be 0. Hence I simply add a very large number to shift them up. If one could make a hash function that worked for arbitrary values then they could use a simple list without having to do this shifting. The shifting + preallocation helps avoid having to create a hash(or it could be thought of a very simple(and fast) hash). – AbstractDissonance Jan 19 '11 at 22:40
0

I implemented logic in Scala with out a Map. It gives duplicate pairs since the counter loops thru entire elements of the array. If duplicate pairs are needed, you can simply return the value pc

  val arr = Array[Int](8, 7, 2, 5, 3, 1, 5)
  val num = 10
  var pc = 0
  for(i <- arr.indices) {
    if(arr.contains(Math.abs(arr(i) - num))) pc += 1
  }

  println(s"Pairs: ${pc/2}")

It is working with duplicates values in the array as well.

Metadata
  • 2,307
  • 8
  • 41
  • 102
0

GOLANG Implementation

func findPairs(slice1 []int, sum int) [][]int {
    pairMap := make(map[int]int)
    var SliceOfPairs [][]int
    for i, v := range slice1 {
        if valuei, ok := pairMap[v]; ok {
            //fmt.Println("Pair Found", i, valuei)
            SliceOfPairs = append(SliceOfPairs, []int{i, valuei})
        } else {
            pairMap[sum-v] = i
        }
    }
    return SliceOfPairs
}
Sumer
  • 2,388
  • 20
  • 21
-1

Javascript solution:

var sample_input = [0, 1, 100, 99, 0, 10, 90, 30, 55, 33, 55, 75, 50, 51, 49, 50, 51, 49, 51];
var result = getNumbersOf(100, sample_input, true, []);

function getNumbersOf(targetNum, numbers, unique, res) {
    var number = numbers.shift();

    if (!numbers.length) {
        return res;
    }

    for (var i = 0; i < numbers.length; i++) {
        if ((number + numbers[i]) === targetNum) {
            var result = [number, numbers[i]];
            if (unique) {
              if (JSON.stringify(res).indexOf(JSON.stringify(result)) < 0) {
                res.push(result);                
              }
            } else {
              res.push(result);
            }
            numbers.splice(numbers.indexOf(numbers[i]), 1);
            break;
        }
    }
    return getNumbersOf(targetNum, numbers, unique, res);
}
gor181
  • 1,846
  • 1
  • 12
  • 12
-1

https://github.com/clockzhong/findSumPairNumber

I did it under O(m+n) complexity cost for both time and memory space. I suspect that's the best algorithm so far.

Clock ZHONG
  • 735
  • 7
  • 22
-4

int [] arr = {1,2,3,4,5,6,7,8,9,0};

var z = (from a in arr from b in arr where 10 - a == b select new { a, b }).ToList;