Reputation:
Array with duplicates [4,4,1]
. Find pairs with sum 5
in O(n)
.
Expected output (4,1)
and (4,1)
and count is 2
.
Approach#1:
Using HashSet
:
public static int twoSum(int[] numbers, int target) {
HashSet<Integer> set = new HashSet<Integer>();
int c = 0;
for(int i:numbers){
if(set.contains(target-i)){
System.out.println(i+"-"+(target-i));
c++;
}
set.add(i);
}
return c;
}
Output is 1
.
Approach #2 as stated in this link:
private static final int MAX = 100000;
static int printpairs(int arr[],int sum)
{
int count = 0;
boolean[] binmap = new boolean[MAX];
for (int i=0; i<arr.length; ++i)
{
int temp = sum-arr[i];
if (temp>=0 && binmap[temp])
{
count ++;
}
binmap[arr[i]] = true;
}
return count;
}
Output 1
.
However the O(nlog n)
solution is using sorting the array:
public static int findPairs(int [] a, int sum){
Arrays.sort(a);
int l = 0;
int r = a.length -1;
int count = 0;
while(l<r){
if((a[l] + a[r]) == sum){
count ++;
System.out.println(a[l] + " "+ a[r]);
r--;
}
else if((a[l] + a[r])>sum ){
r--;
}else{
l++;
}
}
return count;
}
Can we get the solution in O(n)
?
Upvotes: 2
Views: 2586
Reputation: 909
Here is an O(N) Time & Space approach using HashMap
.
class Solution
{
static int getPairsCount(int[] arr, int n, int target)
{
HashMap<Integer,Integer> map = new HashMap<>();
int pairs=0;
for (int i=0; i<n; i++)
{
if (map.containsKey(target - arr[i]))
{
pairs += map.get(target - arr[i]);
for (int j=1; j<=map.get(target - arr[i]); j++)
System.out.print("(" +(target-arr[i])+ "," +arr[i]+ ") ");
}
map.put(arr[i] , map.getOrDefault(arr[i],0)+1);
}
return pairs;
}
public static void main (String [] args)
{
int target = 5;
int [] input = {4, 4, 1};
System.out.println(getPairsCount(input , input.length , target));
target = 10;
input = new int [] {1, 6, 3, 2, 5, 5, 7, 8, 4, 8, 2, 5, 9, 9, 1};
System.out.println(getPairsCount(input , input.length , target));
}
}
Output:
2 (Pairs)
(4,1) (4,1)
13 (Pairs)
(5,5) (3,7) (2,8) (6,4) (2,8) (8,2) (8,2) (5,5) (5,5) (1,9) (1,9) (9,1) (9,1)
Upvotes: 0
Reputation: 11
you can try this also
Map<Integer, List> map = new HashMap<>(); int count = 0;
for (int i = 0; i < arr.length; i++) {
if (map.containsKey(k - arr[i])) {
count += map.get(k - arr[i]).size();
}
List<Integer> test = map.getOrDefault(arr[i], new ArrayList<>());
test.add(i);
map.put(arr[i], test);
}
return count;
Upvotes: 1
Reputation: 3474
You can use your second approach - just change boolean
to int
:
public static void main(String[] args) {
System.out.println(printPairs(new int[]{3, 3, 3, 3}, 6)); // 6
System.out.println(printPairs(new int[]{4, 4, 1}, 5)); // 2
System.out.println(printPairs(new int[]{1, 2, 3, 4, 5, 6}, 7)); // 3
System.out.println(printPairs(new int[]{3, 3, 3, 3, 1, 1, 5, 5}, 6)); // 10
}
public static int printPairs(int arr[], int sum) {
int count = 0;
int[] quantity = new int[sum];
for (int i = 0; i < arr.length; ++i) {
int supplement = sum - arr[i];
if (supplement >= 0) {
count += quantity[supplement];
}
quantity[arr[i]]++; // You may need to check that arr[i] is in bounds
}
return count;
}
Upvotes: 1