Related
I want to find the K smallest elements in an array, and I was able to basically sort my array into a min-heap structure but I am still getting the wrong output.
Here are my inputs:
arr = [9,4,7,1,-2,6,5]
k = 3
Here's the Code:
public static int[] findKSmallest(int[] arr, int k) {
int[] result = new int[k];
int heapSize = arr.length;
// Write - Your - Code
for (int i = (heapSize - 1) / 2; i >= 0; i--) {
minHeap(arr, i, heapSize);
}
for (int j = 0; j < k; j++) {
result[j] = arr[j];
}
return result;
}
public static void minHeap(int[] arr, int index, int heapSize) {
int smallest = index;
while (smallest < heapSize / 2) {
int left = (2 * index) + 1; // 1 more than half the index
int right = (2 * index) + 2; // 2 more than half the index
if (left < heapSize && arr[left] < arr[index]) {
smallest = left;
}
if (right < heapSize && arr[right] < arr[smallest]) {
smallest = right;
}
if (smallest != index) {
int temp = arr[index];
arr[index] = arr[smallest];
arr[smallest] = temp;
index = smallest;
} else {
break;
}
}
}
Here is my expected output:
[-2,1,4]
Though my output is:
[-2,1,5]
Please I would like to know where I went wrong.
After you build your minHeap you have to extract element and appropriately adjust tree. You simply took elements from array by index, which is not how heap works.
I slightly modified your minHeap() method to use recursion and you should check arr[smallest] < arr[left] not the orther way around.
public static int[] findKSmallest(int[] arr, int k) {
int[] result = new int[k];
int heapSize = arr.length;
// Write - Your - Code
for (int i = (heapSize - 1) / 2; i >= 0; i--) {
minHeap(arr, heapSize, i);
}
// extract elements from heap
for (int i = heapSize - 1; i > 0; i--) {
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
minHeap(arr, 0, i);
}
for (int j = 0; j < k; j++) {
result[j] = arr[j];
}
return result;
}
public static void minHeap(int[] arr, int index, int heapSize) {
int smallest = index;
int left = (2 * index) + 1; // 1 more than half the index
int right = (2 * index) + 2; // 2 more than half the index
if (left < heapSize && arr[smallest] < arr[left]) {
smallest = left;
}
if (right < heapSize && arr[smallest] < arr[right]) {
smallest = right;
}
if (smallest != index) {
int temp = arr[index];
arr[index] = arr[smallest];
arr[smallest] = temp;
minHeap(arr, smallest, heapSize);
}
}
Hope this helps. As expected the result is:
[-2, 1, 4]
You can use Arrays.stream(int[]) method:
int[] arr = {9, 4, 7, 1, -2, 6, 5};
int k = 3;
int[] minHeap = Arrays.stream(arr).sorted().limit(k).toArray();
System.out.println(Arrays.toString(minHeap)); // [-2, 1, 4]
Since Java 8 we can do Sorting stream
Alternative code:
Arrays.stream(arr).sorted().boxed().collect(Collectors.toList()).subList(0, k);
where:
int[] arr = {9,4,7,1,-2,6,5};
int k = 3; // toIndex
Alternative code in context and testbench:
public static void main(String[] args) {
int[] arr = {9, 4, 7, 1, -2, 6, 5};
int k = 3; // toIndex
List<Integer> listResult = Arrays.stream(arr)
.sorted().boxed().collect(Collectors.toList()).subList(0, k);
// print out list result
System.out.println("Output of list result: " + listResult);
int[] arrayResult = listResult.stream().mapToInt(i -> i).toArray();
// print out array result
List<String> arrayResultAsString = Arrays.stream(arrayResult)
.boxed().map(i -> String.valueOf(i)).collect(Collectors.toList());
System.out.println("Output of array result: " + arrayResultAsString);
}
Output:
Output of list result: [-2, 1, 4]
Output of array result: [-2, 1, 4]
If K is relatively small to the array size my recommendation is to use selection sort, so it may be a design pattern Strategy - depending on K to array size relation with for example two procedures: selection sort for small K and quicksort for huge K. Instead of playing with design patterns good may be also simple if statement e.g. selection<=30%<quick
that, given an array A of N integers, returns the smallest positive integer (greater than 0) that does not occur in A.
For example, given A = [1, 3, 6, 4, 1, 2], the function should return 5.
Given A = [1, 2, 3], the function should return 4.
Given A = [−1, −3], the function should return 1.
Write an efficient algorithm for the following assumptions:
import java.util.*;
class Main {
/* Utility function that puts all non-positive
(0 and negative) numbers on left side of
arr[] and return count of such numbers */
static int segregate(int arr[], int size)
{
int j = 0, i;
for (i = 0; i < size; i++) {
if (arr[i] <= 0) {
int temp;
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
// increment count of non-positive
// integers
j++;
}
}
return j;
}
/* Find the smallest positive missing
number in an array that contains
all positive integers */
static int findMissingPositive(int arr[], int size)
{
int i;
// Mark arr[i] as visited by making
// arr[arr[i] - 1] negative. Note that
// 1 is subtracted because index start
// from 0 and positive numbers start from 1
for (i = 0; i < size; i++) {
int x = Math.abs(arr[i]);
if (x - 1 < size && arr[x - 1] > 0)
arr[x - 1] = -arr[x - 1];
}
// Return the first index value at which
// is positive
for (i = 0; i < size; i++)
if (arr[i] > 0)
return i + 1; // 1 is added becuase indexes
// start from 0
return size + 1;
}
/* Find the smallest positive missing
number in an array that contains
both positive and negative integers */
static int findMissing(int arr[], int size)
{
// First separate positive and
// negative numbers
int shift = segregate(arr, size);
int arr2[] = new int[size - shift];
int j = 0;
for (int i = shift; i < size; i++) {
arr2[j] = arr[i];
j++;
}
// Shift the array and call
// findMissingPositive for
// positive part
return findMissingPositive(arr2, j);
}
// main function
public static void main(String[] args)
{
int arr[] = { 0, 10, 2, -10, -20 };
int arr_size = arr.length;
int missing = findMissing(arr, arr_size);
System.out.println("The smallest positive missing number is " + missing);
}
}
}
If you need to use stream, the more straightfoward, but not optimal way to do it is to create an infinite stream, starting at 1 and return the first that is not in arr:
int[] arr = { 1, 3, 6, 4, 1, 2 };
Set<Integer> arrSet = Arrays.stream(arr).boxed().collect(Collectors.toSet());
Optional<Integer> found = IntStream.iterate(1, o -> o + 1).boxed()
.filter(value -> !arrSet.contains(value))
.findFirst();
found.ifPresent(System.out::println);
Output
5
As pointed out this is very inefficient, but in terms of computational complexity I believe is optimal, at least for the worst case i.e. the one you have to look at all the elements.
Below you can find the missing positive integer using Streams -
int ar[] = { 0, 10, 2, -10, -20 };
int max = Arrays.stream(ar).max().getAsInt();
System.err.println("maxvalue "+max);
int val = IntStream.range(1, max).filter(i->!Arrays.stream(ar).anyMatch(x->x==i))
.findFirst().getAsInt();
System.out.println(val);
int[] val1 = IntStream.range(1, max).filter(i->!Arrays.stream(ar).anyMatch(x->x==i)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(val1).forEach(System.out::println);
int[] valEven = IntStream.range(1, max).filter(i->Arrays.stream(val1).anyMatch(x->i%2==0)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(valEven).forEach(System.out::println);
int[] valOdd = IntStream.range(1, max).filter(i->!Arrays.stream(val1).anyMatch(x->i%2==0)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(valOdd).forEach(System.out::println);
int[] valOdd1 = IntStream.range(1, max).filter(i->Arrays.stream(val1).noneMatch(x->i%2==0)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(valOdd1).forEach(System.out::println);
int[] valEven1 = IntStream.range(1, max).filter(i->!Arrays.stream(val1).noneMatch(x->i%2==0)).map(p->p).toArray();
System.out.println("------------------");
IntStream.of(valEven1).forEach(System.out::println);
You can also do a mix of stream and primitive int loop:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] numberSet1 = {1, 3, 6, 4, 1, 2};
int[] numberSet2 = {-1, -3};
int[] numberSet3 = {1, 2, 3};
System.out.println(calcularPrimero(numberSet1));
System.out.println(calcularPrimero(numberSet2));
System.out.println(calcularPrimero(numberSet3));
}
public static int calcularPrimero (int[] A) {
//IntStream intStream = Arrays.stream(A).filter(x -> x >= 0).distinct().sorted();
int[] B = Arrays.stream(A).filter(x -> x > 0).distinct().sorted().toArray();
for (int i = 0, index = 1; i < B.length; i++, index++) {
if (index != B[i]) {
return index;
}
}
return B.length + 1;
}
}
I have the below question I am trying to solve:
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
I have the below array as input - [2, 7, 11, 15] with target = 9.
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
This is my code -
import java.util.Random;
public class TwoSum {
static int[] numbers = new int[] {2, 7, 11, 15};
int[] indices = new int[numbers.length];
public static int[] returnIndices(int target, int[] inputArr) {
int[] indices = new int[2];
int randomOne = new Random().nextInt(inputArr.length);
int randomTwo = new Random().nextInt(inputArr.length);
while(true) {
if(target == inputArr[randomOne] + inputArr[randomTwo]) {
indices[0] = randomOne;
indices[1] = randomTwo;
break;
}
}
System.out.println("done");
return indices;
}
public static void main(String[] args) {
int[] output = returnIndices(9, numbers);
}
}
Is this the right way to approach my problem?
You can use a hashmap to store the first array in the following manner:
key value(index in array)
2 - 0
7 - 1
11 - 2
15 - 3
Next get the target element which is 9, and start traversing your given array from index 0.
Element at index 0 is 2 --> calculate (9-2) = 7 --> check if 7 is a key in the hashmap
Additional Note: You need to take care of the following case:
arr = [3, 2, 1, 1] target = 6 (no answer exists in this case, but by the above method, when you calculate 6-3 = 3 you get index 0 as the answer.)
But this can easily be taken care of by checking whether (target-arr[i] == arr[i]) returns true or not. If it returns true and if the hashmap has two indices stored at the key arr[i], then return it as an answer, else proceed to the next element.
There are various ways to solve this question:
Hashmap way - #mettleap answer has covered that one.
Sort-Array way - I am going to explain its pseudo code to you.
Let us take an example to see it in action first. We are given arr = [5, 2, 1, 9, 7] elements in an array, and we are to find the indices of two elements if we can make 8.
If you look closely, then you will know if we sum 3rd + last element in an array, we will get 8, which means 2 and 4 would be our answer. So How would be land there? Let us go step by step
Maintain a separate array of the same size, it will hold the indices of arr in its initial setup.
[5, 2, 1, 9, 7] = arr
[0, 1, 2, 3, 4] = index_arr
Now sort arr in increasing order, and also sort the index_arr such that index of elements in arr in their initial setup is still in place.
[1, 2, 5, 7, 9] = arr
[2, 1, 0, 4, 3] = index_arr
Use the below pseudo code:
low = 0
high = length of arr - 1
while (low < high) {
sum = arr[low] + arr[high]
if (sum == number) {}
print "index_arr[low]" and "index_arr[high]"
break the loop and exit
} else if ( sum < number ) {
low = low + 1
} else {
high = high - 1
}
}
Let us see psuedo code in action:
[1, 2, 5, 7, 9] = arr
[2, 1, 0, 4, 3] = index_arr
Iteration # 01
low = 0 and high = 4
sum = arr[0] + arr[4] = 1 + 9 = 10
10 > 8 , means 'else' will be executed high = high - 1 = 4 - 1 = 3
Iteration # 02
low = 0 and high = 3
sum = arr[0] + arr[3] = 1 + 7 = 8
8 == 8 , means first 'if' condiion will execute, and will indices and exit the loop
Time Complexity - O(n)
Space Complexity - O(n)
I have tried it in c#, It may help..
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
int[] nums = { 2, 7, 11, 15 };
int target = 9;
int[] result= TwoSumNumbers(nums, target);
}
public static int[] TwoSumNumbers(int[] nums, int target)
{
Dictionary<int, int> numsDict = new Dictionary<int, int>();
for (int i = 0; i < nums.Length; i++)
{
int num = nums[i];
if (numsDict.TryGetValue(target - num, out int index))
{
return new[] { index, i };
}
numsDict[num] = i;
}
return null;
}
}
class Solution {
public int[] twoSum(int[] nums, int target) {
int [] answer = new int[2];
Map<Integer,Integer> values = new HashMap<Integer,Integer>();
for ( int i=0; i < nums.length; i++){
values.put(nums[i],i);
}
for ( int i=0; i < nums.length; i++){
int val = target - nums[i];
Integer secondIndex = values.get(val);
if ( secondIndex != null && secondIndex != i){
answer[0] = i;
answer[1] = secondIndex;
return answer;
}
}
return answer;
}
}
C# Version
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
namespace MyBasics
{
class ArrayIndexForTarget
{
public static void Main()
{
ArrayIndexForTarget find = new ArrayIndexForTarget();
int[] arr = new int[] { 9, 2, 3, 9, 10 };
int target = 11;
var result = find.IndexFinder(arr, target);
Console.ReadKey();
}
public int[] IndexFinder(int[]myArray,int target)
{
int[] arr = new int[2];
Dictionary<int, int> dict = new Dictionary<int, int>();
for (int p=0; p < myArray.Length; p++)
{
int numberToFind = target - myArray[p];
if (dict.ContainsValue(numberToFind))
{
arr[0] = dict.FirstOrDefault(x => x.Value == numberToFind).Key;
arr[1] = p;
return arr;
}
else
{
dict.Add(p,myArray[p]);
}
}
return arr;
}
}
}
class Solution {
function twoSum($nums, $target) {
$lenght = count($nums);
$indices = array();
for($i = 0; $i<$lenght-1; $i++){
for($j=$i+1; $j<$lenght; $j++){
if(($nums[$i]+$nums[$j]) == $target){
$indices[] = $i;
$indices[] = $j;
return $indices;
}
}
}
} }
private static int[] findNumbersToAdd(int target, int[] array) {
int[] answer = {-1, -1};
int length = array.length;
for (int i = 0; i < length; i++) {
int var1 = array[i];
for (int j = i + 1; j < length; j++) {
int var2 = array[j];
if (var1 + var2 == target) {
answer[0] = i;
answer[1] = j;
break;
}
}
}
return answer;
}
Given you aren't focused on performance I would think a brute force approach would be fine. Here is a solution using streams and records.
record IndexPair(int index1, int index2) { };
IntStream.range(0, arr.length).boxed()
.flatMap(i1 -> IntStream.range(i1, arr.length)
.filter(i2 -> arr[i1] + arr[i2] == target)
.mapToObj(i2 -> new IndexPair(i1, i2))
.forEach(ip -> ...);
If you only want one solution then you could use findAny instead of forEach.
I tried this question and implement it using HashMap in Java and it works completely fine.
public class Solution {
public int[] twoSum(final int[] A, int B) {
HashMap<Integer,Integer> hm=new HashMap<>();
int index1=Integer.MAX_VALUE;
int index2=Integer.MAX_VALUE;
int diff=0;
for(int i=0;i<A.length;i++){
diff=B-A[i];
if(hm.containsKey(diff)){
index2=i;
index1=hm.get(diff);
return new int[] {index1+1,index2+1};
}else{
if(!hm.containsKey(A[i])){
hm.put(A[i],i);
}
}
}
// If Arrays doesnt have such pairs
if(index2 == (Integer.MAX_VALUE) || index1 == (Integer.MAX_VALUE)){
return new int[] {};
}
return new int[] {index1+1,index2+1};
}
}
here is a simple solution with 2 running loops,
assuming the following
you only need 2 numbers to get to the target.
the solution exists (therefor no need to validate).
public int[] TwoSum(int[] nums, int target) {
for (int i=0; i< nums.Length; i++){
for (int j=i+1; j< nums.Length; j++){
if (nums[i] + nums[j] == target){
return new int[]{i,j};
}
}
}
return null;
}
public int[] sumofTwo(int[] numbers, int target)
{
int[] answer = new int[2];
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
for(int i = 0 ; i < numbers.length ; i++)
{
if(map.containsKey(target - numbers[i]))
{
answer[0] = map.get(target - numbers[i]);
answer[1] = i;
return answer;
}
else
{
map.put(numbers[i],i);
}
}
return null;
}
}
public class Main {
public static void main(String[] args) {
int [] arr = {4,7,1,-3,2};
for(int i=0; i<arr.length-1; i++)
{
for(int j=0; j<=arr.length-2; j++)
{
if((arr[i]+arr[j+1])==6)
{
System.out.println("indices = "+"["+i +","+(j+1)+"]");
}
}
}
}
}
I am trying to count the numbers of pairs in an array such that each pair gives the sum of an integer!
I used the following code :
public static int SumPairs(Integer []input, int k){
Map<Integer, Integer> pairs = new HashMap<Integer, Integer>();
int tmp=0;
//System.out.println(pairs.toString());
for(int i=0;i<input.length;i++){
if(pairs.containsKey(input[i])){
System.out.println(pairs.containsKey(input[i]));
System.out.println(input[i] +", "+ pairs.get(input[i]));
input[i]=0;
tmp++;
}
else
pairs.put(k-input[i], input[i]);
}return tmp;
}
the problem is ; for example when my array is 1 2 2 2 3 4 4 4
and sum = 5
it compute as following
(4,1)
(4,1)
(4,1)
(3,2)
I want to prevent the method from using a number more than once !!
so the output will be
(4,1)
(3,2)
I hope this can help
def numberOfPairs(a, k):
# Let's do a o(n) approach by maintaining all the compliments of the K in a
# visited set
compliments = set()
result = set()
for v in a:
# See if the element is in the compliments set, if so thats the pair
if v in compliments:
result.add((v, k-v))
# If the element is not found in visited save the compliment of it in the visited set
else:
compliments.add(k-v)
return len(result)
I use a map storing values and their frequencies:
public static int SumPairs(Integer[] input, int k){
Map<Integer, Integer> frequencies = new HashMap<>();
int pairsCount = 0;
for(int i=0; i<input.length; i++){
int value = input[i];
int complement = k - input[i];
if(frequencies.containsKey(complement)){
int freq = frequencies.get(complement) - 1;
pairsCount++;
//System.out.println(value + ", " + complement);
if(freq == 0){
frequencies.remove(complement);
}else{
frequencies.put(complement, freq);
}
}else{
if(frequencies.containsKey(value)){
frequencies.put(value, frequencies.get(value) + 1);
}else{
frequencies.put(value, 1);
}
}
}
return pairsCount;
}
This works for all the test cases I could think of. Please add in the comment section any test case that this code fails so that I can fix it. If it works, please accept the solution.
public class DistinctPairs {
private static int count(int target, int... arr) {
int count = 0;
Set<String> seen = new HashSet<>();
Set<Integer> set = new HashSet<>();
for (int i = 0; i < arr.length; i++) {
int k = target - arr[i];
int[] pair = new int[]{k, arr[i]};
Arrays.sort(pair);
String s = Arrays.toString(pair);
if (set.contains(k) && !seen.contains(s)) {
count++;
seen.add(s);
// uncomment this print statement to print the distinct pairs
// System.out.println(s);
} else {
set.add(arr[i]);
}
}
return count;
}
// test suite and driver method
public static void main(String[] args) {
System.out.println(count(10, 1, 2, 3, 6, 7, 8, 9, 1) == 3);
System.out.println(count(47, 6, 1, 3, 46, 1, 3, 9) == 1);
System.out.println(count(9, 3, 2, 1, 45, 27, 6, 78, 9, 0) == 2);
System.out.println(count(9, 3, 3, 2, 1, 45, 27, 6, 78, 9, 0) == 2);
System.out.println(count(6, 1, 5, 7, -1) == 2);
System.out.println(count(6, 1, 5, 7, -1, 5) == 2);
System.out.println(count(2, 1, 1, 1, 1) == 1);
System.out.println(count(5, 1, 2, 2, 2, 3, 4, 4, 4) == 2);
System.out.println(count(8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4) == 1);
System.out.println(count(7, 1, 5, 66, 2, 3, 4, 7, 0, 2, 5) == 3);
System.out.println(count(5) == 0);
System.out.println(count(5, 1) == 0);
System.out.println(count(7, 3, 4) == 1);
}
}
Another approach can be to follow the classic solution of Two Sum Problem and add the pairs in a set as you find them, all this in the same pass. This set will be of a custom wrapper class with arr[i] and (target - arr[i]) as it's members and you'll need to override hashcode() and equals() methods in such a way that (a,b) is the same as (b,a). At the end simply return the size of the set. This approach will have the same time and space complexity in Big-O terms as the first approach.
int count(int target, int... nums) {
Set<Pair> uniPairs = new HashSet<>();
Set<Integer> seen = new HashSet<>();
for (int i = 0; i < nums.length; i++) {
int diff = target - nums[i];
if (seen.contains(diff)) {
Pair pair = new Pair(nums[i], diff);
uniPairs.add(pair);
}
seen.add(nums[i]);
}
return uniPairs.size();
}
class Pair {
int a;
int b;
public Pair (int a, int b) {
this.a = a;
this.b = b;
}
#Override
public boolean equals(Object obj) {
Pair pair2 = (Pair) obj;
return ((a == pair2.a) && (b == pair2.b)) || ((b == pair2.a) && (a == pair2.b));
}
#Override
public int hashCode() {
return Objects.hash(a, b) + Objects.hash(b, a);
}
}
public static int sumPairs(Integer[] input, int sum){
List<Integer> complementaries = new ArrayList<>(input.length);
int pairs = 0;
for(Integer number : input){
if(complementaries.contains(number)){
complementaries.remove(number);
pairs++;
}
else{
complementaries.add(sum-number);
}
}
return pairs;
}
Now it should work perfectly.
The complementaries array is used just for keeping track of the numbers needed for making the sum. If it contains the number it means that we iterated over its complementary before, so we can just add one pair and remove the number from the list of complementaries. Oherwise we add the complementary of the current number to the list without incresing the pairs counter.
The code takes an array and returns all possible pairs that have sum as specified. As the question asks to print number of pairs and not the pairs, the length of array divided by 2 would give the desired answer.
int notInArray(float a[],float m,int n)
{
int i,j,k;
for(i=0;i<n;i++)
{
if(a[i] == m)
return 0;
}
return 1;
}
int main() {
int i,j,k;
int n;
scanf("%d",&n); //Input the number of elements in array.
float arr[n];
for(i=0;i<n;i++)
scanf("%f",&arr[i]); //input the array elements
float copyArr = arr[0];
float m;
if (n == 0)
return 0;
scanf("%f",&m); //input the sum
float resArr[n];
int b;
int a=b=0;
for(i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
{
if(arr[i]+arr[j]==m && notInArray(resArr,arr[i],n))
{
resArr[a++] = arr[i];
resArr[a++] = arr[j];
//printf("%.0f %.0f\n",arr[i],arr[j]);
}
}
}
printf("All possible pairs: \n");
for(i = 0;i<a;i+=2)
printf("%.0f %.0f\n",resArr[i],resArr[i+1]);
int len = (int)( sizeof(resArr) / sizeof(resArr[0]) )
printf("Number of such pairs: %d",len);
return 0;
}
public void distinctPairs(int[] arr, int k){
int length = arr.length;
int count = 0;
Map<Integer,Integer> pairs = new HashMap<Integer,Integer>();
for(int i=0;i<length;i++){
for(int j=i+1;j<length;j++){
if(arr[i]+arr[j] == k ){
if(!(pairs.containsKey(arr[j])&&pairs.containsValue(arr[i])))
pairs.put(arr[i], arr[j]);
}
}
}
count = pairs.size();
System.out.println("Pairs are "+pairs+" count = "+count);
}
This works for me. Steps I followed.
Check if sum of a pair is equal to required(k).
Check if the pair doesn't already exist in the map.
We can use the hashmap to store all values of the array. Then iterate over the array and check if the map contains (K - a[i] ). If the map contains then increment count and remove both keys from the map.
private int getDistinctPair(int k,int[] input){
HashMap<Integer,Integer> map = new HashMap<>();
int pairs = 0;
for (int i = 0; i < input.length-1; i++) {
map.put(input[i], input[i]);
}
for (int i = 0; i <input.length-1 ; i++) {
int diff = k - input[i];
if(map.containsKey(diff)){
pairs++;
map.remove(diff);
map.remove(input[i]);
}
}
return pairs;
}
You can slove by using below code:
def countPairs(arr, k):
possible_maps = []
for num in arr:
pair_matches = list(filter(lambda n: n + num == k, arr))
if len(pair_matches) > 0:
possible_maps += list(map(lambda nm: (num, nm), pair_matches))
return len(set(map(lambda pair: ','.join(str(n) for n in sorted(pair)), possible_maps)))
Hope this may help you.
My C# way to do this in a single loop with just another list to store temporary diff values.
private static int SumPairs(int[] arr, int sum)
{
Dictionary<int, int> frequency = new Dictionary<int, int>();
List<int> temp = new List<int>();
int count = 0;
foreach (int i in arr)
{
int diff = sum - i;
if (!frequency.ContainsKey(i))
{
if (temp.Contains(i))
{
frequency.Add(i, diff);
count++;
}
else
{
temp.Add(diff);
}
}
};
return count;
}
my C# implementation using Tuple
static List<Tuple<int,int>> GetUniquePairs(int[] arr, int sum)
{
Dictionary<Tuple<int, int>, int> kvp = new Dictionary<Tuple<int, int>, int>();
List<Tuple<int,int>> result = new List<Tuple<int,int>>();
int length = arr.Length;
for(int i = 0;i < length; i++)
{
int j = i + 1;
while (j < length)
{
if(arr[i]+arr[j] == sum)
{
Tuple<int, int> key = new Tuple<int, int>(arr[i], arr[j]);
if (!kvp.ContainsKey(key))
kvp.Add(key, 1);
}
j++;
}
}
var keys = kvp.Keys;
foreach(var k in keys)
{
result.Add(k);
}
return result;
}
The Simplest Solution of your problem of finding distinct pair:
public static int SumPairs(int[] input, int k) {
Map<Integer, Integer> pairs = new HashMap<Integer, Integer>();
int tmp = 0;
for (int data : input) {
if (pairs.containsKey(k - data) && pairs.get(k - data) == 0) {
tmp++;
pairs.put((k - data), pairs.get(k - data) + 1);
} else if (!pairs.containsKey(data)) {
pairs.put(data, 0);
}
}
return tmp;
}
It has been tested for 1 2 2 2 3 4 4 4 and sum = 5. Also for 4 4 4 4 4 4 4 4 4 4 4 4 4 4 and sum = 8.
If any confusion feel free to ask me. Cheers.
import java.util.HashSet;
public class DistinctPairs {
static int numberOfPairs(int[] arr,int k)
{
HashSet<String> s=new HashSet<String>();
int n=arr.length;
int sum=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
sum=arr[i]+arr[j];
if(i==j)
{
continue;
}
else
{
if(sum==k)
{
String l=String.valueOf("("+arr[i]+","+arr[j]+")");
StringBuilder sb=new StringBuilder(l);
String rl=sb.reverse().toString();
if(s.add(l)==false)
{
}
}
}
}
}
System.out.println(s.toString());
return s.size()/2;
}
public static void main(String args[])
{
int b[]={1,5,66,2,3,4,7,0,2,5};
int size=numberOfPairs(b,5);
System.out.println(size);
}
}
I got the largest number and smallest number from the string. But how do I find second largest number and third largest number in this java code from this problem? which code should i use? Please explain
public class Problem1
{
public static void main(String[] args) {
int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// int b[] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
Problem1 app = new Problem1();
app.scrambleArray(a);
app.print(a);
// Usage enable assertions: -ea to VM arguments
int result = app.findInt(a, 10);
assert (result == 10) :
String.format("Expected <10> but was <%d>", result);
result = app.findInt(a, 11);
assert (result == -1) :
String.format("Expected <-1> but was <%d>", result);
System.out.printf("Largest Number is : %d%n", app.getMax(a));
app.print(app.reverseArray(a));
}
public void scrambleArray(int[] a) {
for (int i = 0; i < a.length; i++) {
int pos = new Random().nextInt(a.length);
int tmp = a[i];
a[i] = a[pos];
a[pos] = tmp;
}
}
public void print(int[] a) {
System.out.println(Arrays.toString(a));
}
public int getMax(int[] a) {
int max = a[0];
for (int i = 1; i < a.length; i++) {
max = Math.max(a[i], max);
}
return max;
}
public int findInt(int[] a, int value) {
int result = -1;
for (int i : a) {
if (value == i) {
result = value;
break;
}
}
return result;
}
public int[] reverseArray(int[] a) {
int[] results = new int[a.length];
for (int i = 0, idx = a.length - 1; i < a.length; i++, idx--) {
results[i] = a[idx];
}
return results;
}
}
Use Arrays.sort() method to sort your integer array
int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
Arrays.sort(a);
System.out.println("largest value: " + a[a.length - 1]);
System.out.println("second largest: " + a[a.length - 2]);
The prior answer is generally a good solution. The exception is if the number of elements in the array is very big and performance matters. In that case, it may be faster to keep the N largest elements in a sorted set, and avoid sorting the whole list:
public int[] getNLargest(int[] in, int n){
TreeSet<Integer> large = new TreeSet<Integer>();
for(int i : in){
if(large.size() < n){
large.add(i);
} else if(i > large.first().intValue()){
large.remove(large.first());
large.add(i);
}
}
int[] result = new int[large.size()];
int index = 0;
for(Integer i : large){
result[index] = i.intValue();
index++;
}
return result;
}
import java.util.*;
public class SecondLargestInArray
{
public static void main(String[] args)
{
int arr[] = {14,46,47,86,92,52,48,36,66,85,92};
int largest = arr[0];
int secondLargest = arr[0];
System.out.println("The given array is:" );
for (int i = 0; i < arr.length; i++)
{
System.out.print(arr[i]+"\t");
}
for (int i = 0; i < arr.length; i++)
{
if (arr[i] > largest)
{
secondLargest = largest;
largest = arr[i];
}
else if((arr[i]<largest && arr[i]>secondLargest) || largest==secondLargest)
{
secondLargest=arr[i];
}
}
System.out.println("\nLargest number is:" + largest);
System.out.println("\nSecond largest number is:" + secondLargest);
}
}