Reputation: 53
I was solving the problem on hackerrank. I had two approaches in my mind :
input : unsorted array(a) and k
First Approach :
1) Sort the array
2) for each array element a[i] ,find the element a[i]+K using binary search.If found increament the count and break the inner loop.
Second Approach :
1) Sort the array
2) for each array element a[i] ,find the element a[i]+K using linearsearch.If found increament the count and break the inner loop.
I found the First approach to be better as it will solve the problem in n(logn). But when multiple test cases are on the solutions the approach 2 takes lesser time . Can some one please explain why ?
Below are the code for the two approaches :
First Approach Code :
static int pairs(int[] a,int k) {
/* Complete this function */
int temp;
int len=a.length;
int count=0;
int beg;
int mid;
int end;
int midVal;
Arrays.sort(a);
for(int i=0;i<len-1;i++){
temp=a[i]+k;
beg=i+1;
end=len-1;
for(int l=beg;l<len;l++){
mid=(beg+end)/2;
midVal=a[mid];
if(midVal==temp){
count++;
break;
}
else if(midVal>temp){
end=mid-1;
}
else{
beg=mid+1;
}
}
}
return count;
}
Second Approach Code :
static int pairs(int[] a,int k) {
/* Complete this function */
int temp;
int len=a.length;
int count=0;
Arrays.sort(a);
for(int i=0;i<len;i++){
temp=a[i];
for(int j=i+1;j<len;j++){
if(temp-a[j]==-k){
count++;
break;
}
}
}
return count;
}
Upvotes: 4
Views: 24368
Reputation: 51
My solution
System.out.println("findPair:"+findPair(new int[]{4,7,1,2,5,3,0,7,8,5,2}, 3));
public static int findPair(int[] nums, int target){
Arrays.sort(nums);
int count = 0;
String pairText = "";
for(int i =0; i < nums.length;i++){
for(int j =i+1; j < nums.length;j++){
if(nums[j]-nums[i] == target && (!pairText.equals(nums[i]+", "+nums[j]))){
//System.out.println(nums[i]+", "+nums[j]);
pairText = nums[i]+", "+nums[j];
count++;
}
}
}
return count;
}
Upvotes: 0
Reputation: 7
static boolean checkDuplicatesWithinK(int arr[], int k)
{
// Creates an empty hashset
HashSet<Integer> set = new HashSet<>();
// Traverse the input array
for (int i=0; i<arr.length; i++)
{
// If already present n hash, then we found
// a duplicate within k distance
if (set.contains(arr[i]))
return true;
// Add this item to hashset
set.add(arr[i]);
// Remove the k+1 distant item
if (i >= k)
set.remove(arr[i-k]);
}
return false;
}
public static void main (String[] args)
{
int arr[] = {10, 5, 3, 4, 3, 5, 6};
if (checkDuplicatesWithinK(arr, 3))
System.out.println("Yes");
else
System.out.println("No");
}
Upvotes: -1
Reputation: 912
private static int CountDistinctPairs(int[] nums, int k) {
// TODO Auto-generated method stub
HashMap<Integer, Boolean> map = new HashMap<Integer, Boolean>();
HashSet<String> set = new HashSet<String>();
for(int i =0;i < nums.length;i++){
map.put(nums[i],true);
}
for (int i = 0 ; i < nums.length; i++){
if(map.containsKey(nums[i]+k)){
String a = "";
if(nums[i]<nums[i]+k){
a = "("+nums[i]+","+(nums[i]+k)+")";
}
else{
a = "("+(nums[i] + k)+","+nums[i]+")";
}
set.add(a);
}
}
System.out.println(set);
return set.size();
}
Upvotes: 0
Reputation: 989
You can also use set no need to use hashmap
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int[] firstLine = Stream.of(in.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
int count = firstLine[0];
int diff = firstLine[1];
Set<Integer> numbers = new HashSet<Integer>(Stream.of(in.readLine().split(" ")).map(Integer::valueOf).collect(Collectors.toList()));
int pairCount = 0;
for (Integer number : numbers) {
pairCount += (numbers.contains(number+diff) ? 1:0);
}
System.out.println(pairCount);
}
Upvotes: 0
Reputation: 12705
In your 1st code, your inner loop termination condition is incorrect. It should terminate if the beg
and end
pointers cross each other.
Change it to while (beg <= end)
or for (; beg <= end; )
Also, for the second approach there is no need for sorting the array.
Upvotes: 0
Reputation: 6246
The first approach is the best here among the two but there is better approach than both:-
Here a pseudo code for a better approach:-
for(i=0;i<Arr.length;i++) {
Hashmap.add(Arr[i])
}
count=0;
for(j=0;j<Arr.length;j++) {
if(Hashmap.containsKey(Arr[j]+k))
count++;
}
Time complexity: O(N) whereas your approach = O(NlogN)
Edit:-
Note:- My approach has extra space complexity of O(N) for Hash table whereas suggested approach is inplace.
Upvotes: 7