Lifts are usually limited in capacity, both in space (persons) as in load (kgs). Imagine we have
a small lift which is capable of transporting a maximum of 6 persons and a maximum load of
500kg. Suppose 13 people are waiting with the following weights: 10, 30, 40, 41, 80, 90, 50, 55,
92, 66, 82, 62 and 70kg. Write a recursive program that finds a group of people that does not
exceed the maximum capacities, but has the maximum possible load in kg. (Hint: there is a valid
solution that exceeds 470kg)
public static void main (String[] Args)
{
ArrayList<Integer> s = new ArrayList<Integer>(); //List of unexplored
int[] weight0 = { 10, 30, 40, 41, 80, 90, 50, 55, 92, 66, 82, 62,70}; //Initial state
int target = 500; //Goal state
System.out.println(liftGroup(weight0,0,target, s) + " way(s)"); //Recursive function
}
static int liftGroup (int[] weight,int c,int target, ArrayList<Integer> s){
assert weight != null : "array should be initialized";
assert c >= 0 && c <= weight.length;
assert s != null : "ArrayList should be initialized";
int sumOfUntried = 0;
if (c > 6) {
showSoulution(s);
return 1;
}
else if (target < 0) {
return 0;
}
else if (c >= weight.length) { //that's okay?
return 0;
}
int min = weight[c];
for (int i = c; i < weight.length; i++) {
sumOfUntried += weight[i];
if(weight[i]<min)
min=weight[i];
}
if(min>target) // If you find one BIG fatty
{
return 0;
}
if (sumOfUntried > target) { //Correct
return 0;
}
else {
s.add(weight[c]);
int with = liftGroup(weight, c + 1, target - weight[c], s);
s.remove(s.size() - 1);
int without = liftGroup(weight, c + 1, target, s);
return with + without;
}
}
/*
* Prints the ArrayList with the solution
*/
private static void showSoulution(ArrayList<Integer> s)
{
assert s != null : "ArrayList should be initialized";
System.out.println("Solution: " + s);
}}
My problem is understanding and using the base case:
When the number of persons does not exceed the maximum limits. You've got a solution.
But how do I comply with the two goals?
Here's a little bit of a messy solution*, which I threw together with credit from here, here and here.
Basically, for each iteration, add the combination, and its sum to a HashMap.
Then sort the HashMap by value.
Finally, loop through HashMap and find closest value to your target.
static Map<String, Integer> myMap = new HashMap<>();
static void combinationUtil(int arr[], int data[], int start,
int end, int index, int r) {
int sum = 0;
StringBuilder sb = new StringBuilder();
if (index == r) {
for (int j = 0; j < r; j++) {
sb.append(data[j]).append(",");
sum += data[j];
System.out.print(data[j] + " ");
}
myMap.put(sb.toString(), sum);
sum = 0;
sb = new StringBuilder();
System.out.println("");
return;
}
for (int i = start; i <= end && end - i + 1 >= r - index; i++) {
data[index] = arr[i];
combinationUtil(arr, data, i + 1, end, index + 1, r);
}
}
static void printCombination(int arr[], int n, int r) {
int data[] = new int[r];
combinationUtil(arr, data, 0, n - 1, 0, r);
}
public static void main(String[] args) {
int arr[] = {10, 30, 40, 41, 80, 90, 50, 55, 92, 66, 82, 62, 70};
int r = 6; //as you have 6 people
int n = arr.length;
printCombination(arr, n, r);
myMap = sortByValue(myMap);
System.out.println(searchClosest(myMap, 500)); //500 is the target
}
public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
return map.entrySet()
.stream()
.sorted(Map.Entry.comparingByValue(/*Collections.reverseOrder()*/))
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(e1, e2) -> e1,
LinkedHashMap::new
));
}
public static String searchClosest(Map<String, Integer> map, int value) {
double minDistance = Double.MAX_VALUE;
String bestString = null;
for (Map.Entry<String, Integer> entry : map.entrySet()) {
double distance = Math.abs(entry.getValue() - value);
if (distance < minDistance) {
minDistance = distance;
bestString = entry.getKey();
}
}
return bestString;
}
Here's an online example with int arr[] = {1,2,3,4,5,6,7,8}; and the permutations set to 3, and target of 14.
*This is just copied/pasted with one or two minor modifications but is more just an idea of how to get your solution
Related
This is a perceptual question.
I want to know why there is an interference with these two independent methods.
I know both are reading the same array (my_array)
independently every response of the methods is correct. But when I turn on both of them (min and max methods), the response of the below method is wrong.
This is my code:
public class myPractice {
public static int max(int[] my_array1) {
int i = 0;
int max = my_array1[i];
for(i = 0; i < my_array1.length-1; i++) {
if(my_array1[i] > my_array1[i+1]) {
my_array1[i+1] = my_array1[i];
max = my_array1[i];
}else {
max = my_array1[i+1];
}
}
System.out.println("Max= " +max);
return max;
}
public static int min(int[] my_array2) {
int j = 0;
int min = my_array2[j];
for(j = 0; j < my_array2.length-1; j++) {
if(my_array2[j] < my_array2[j+1]) {
my_array2[j+1] = my_array2[j];
min = my_array2[j];
}else {
min = my_array2[j+1];
}
}
System.out.println("Min= " +min);
return min;
}
public static void main(String args[]) {
int[] my_array = {25, 14, 56, 5, 36, 89, 77, 18, 29, 49};
max(my_array);
min(my_array);
}
}
The issue is that you are altering the input array in the min and max methods:
my_array1[i+1] = my_array1[i];
As a result, in the next call, you are manipulating an array different from the initial one. As a matter of fact, in your script, max(my_array) sets my_array equals to [25, 25, 56, 56, 56, 89, 89, 89, 89, 89].
You can simplify min and max as the following ones:
public static int max(int[] myArr) {
int max = myArr[0];
for (int i = 1; i < myArr.length; i++){
if (myArr[i] > max)
max = myArr[i];
}
return max;
}
public static int min(int[] myArr) {
int min = myArr[0];
for (int i = 1; i < myArr.length; i++){
if (myArr[i] < min)
min = myArr[i];
}
return min;
}
Furthermore, I want to recommend some best practices:
use the camel case when programming in java. Write myArray instead of my_array;
print the result of a method in the main:
public static void main(String[] args) {
int[] myArray = {25, 14, 56, 5, 36, 89, 77, 18, 29, 49};
System.out.println("Max = " + max(myArray));
System.out.println("Min = " + min(myArray));
}
This question already has answers here:
Java Sort List of Lists
(5 answers)
Closed 1 year ago.
I am trying to sort a List<List<Integer>> lexicographical manner. But I'm unable to achieve the goal and don't get where is the issue.
List<List<Integer>> result = new ArrayList<List<Integer>>();
result.add(Arrays.asList(1, 3, 76, 99));
result.add(Arrays.asList(1, 2, 84, 92));
result.add(Arrays.asList(1, 1, 76, 99));
java.util.Collections.sort(result, (item1, item2) -> {
if (item1.get(0) > item2.get(0) || item1.get(1) > item2.get(1) || item1.get(2) > item2.get(2)
|| item1.get(3) > item2.get(3)) {
return 1;
} else {
return -1;
}
});
Expected output:
[[1, 1, 76, 99], [1, 2, 84, 92], [1, 3, 76, 99]]
But I'm getting
[[1, 3, 76, 99], [1, 2, 84, 92], [1, 1, 76, 99]]
I want that index wise smallest number will come first. In the example, all three lists have 1 at the first position, so no change. At the second position, 3rd list has 1 which is the minimum among the three so 3rd list will be moved to the first. Then considering the 2nd item of 2nd and 3rd list 2 is lower so second list will remain at the 2nd position.
The condition you have is wrong. When item1.get(0) < item2.get(0) you simply continue your short-circuited comparison instead of returning -1. Also, any time you have a comparator that does not return 0, I get automatically suspicious.
A simple fix would be to use a loop:
for(int i = 0; i < 4; i++) {
int i1 = item1.get(i);
int i2 = item2.get(i);
if(i1 < i2) {
return -1;
} else if(i1 > i2) {
return 1;
}
}
return 0;
You could simplify the loop to
for(int i = 0; i < 4; i++) {
int d = item1.get(i) - item2.get(i);
if(d != 0) {
return d;
}
}
return 0;
You can do it in a generic way, based on MatinS answer:
class ListComparator<T extends Comparable<T>> implements Comparator<List<T>> {
#Override
public int compare(List<T> o1, List<T> o2) {
for (int i = 0; i < Math.min(o1.size(), o2.size()); i++) {
int c = o1.get(i).compareTo(o2.get(i));
if (c != 0) {
return c;
}
}
return Integer.compare(o1.size(), o2.size());
}
}
Then sorting is easy
List<List<Integer>> listOfLists = ...;
Collections.sort(listOfLists, new ListComparator<>());
Building off of Mad Physicist's answer, here is a more general solution and usage:
public final class SortingListOfListExample {
public static void main(final String[] args) {
final List<List<Integer>> result = new ArrayList<>();
result.add(List.of(1, 3, 76, 99));
result.add(List.of(1, 2, 84, 92));
result.add(List.of(1, 1, 76, 99));
System.out.println(result);
result.sort(new ListComparator<>());
System.out.println(result);
}
private static final class ListComparator<T extends Comparable<T>> implements Comparator<List<T>> {
#Override
public final int compare(final List<T> list1, final List<T> list2) {
final int minSize = Math.min(list1.size(), list2.size());
for(int i = 0; i < minSize; i++) {
// Be wary of nulls.
final int compareResult = list1.get(i).compareTo(list2.get(i));
if(compareResult != 0) {
return compareResult;
}
}
return Integer.compare(list1.size(), list2.size());
}
}
}
I try to achieve the positions in which the elements located in these have the least distance between them? i have this code in java 11:
public class Main {
public static void main(String[] args) {
int [] arr= {5, 50, 3, 42, 18, 16, 8, 30, 44}; // Array
menorD l = new menorD();
menorD.MinD(arr);
}
}
public class menorD {
static int arr_zise;
public static void minD (int [] arr) {
arr_zise = arr.length;
int i, j;
int minD=0;
for(i=0;i<arr_zise; i++) {
for(j=0;j<arr_zise; j++) {
if(arr[i]!=arr[j]) {
minD=arr[i]-arr[j];
System.out.print(" i="+ arr[i]+ " j="+ arr[j]+ " minD es: "+Math.abs(min));
System.out.println();
}
}
}
}
}
i try to find this:
arr = {5, 50, 3, 42, 18, 16, 8, 30, 44}
my Dmin would be the difference between the numbers with less distance between them, in this case,
Dmin1 = 5-3 = 2;
Dmin2 = 18-16 = 2;
Dmin3 44-42 = 2;
Without repeating the index of the number in the array. I have made this code but I have difficulty finding what I am looking for.
Ideally when handling data that is logically grouped together, you should abstract away a class to encapsulate it. In your case you want to keep track of every possible distance combination. Each Combination should keep track of:
Indexes of the values.
Values themselves.
Distance.
Which one is low and which one is high.
Out of these 3. and 4. can be computed from 1. and 2.
class Combination {
int indexA, indexB, valueA, valueB;
public Combination(int[] array, int indexA, int indexB) {
this.indexA = indexA;
this.indexB = indexB;
this.valueA = array[indexA];
this.valueB = array[indexB];
}
public int getDistance() { ... }
public int getHigh() { ... }
public int getLow() { ... }
public int getHighIndex() { ... }
public int getLowIndex() { ... }
}
With such data structure (class) available, you can construct objects for each of the possible combinations (without repetitions of course - pay attention how j starts variably at i + 1 to do not repeat possible combinations):
List<Combination> combinations = new ArrayList<>();
for (int i = 0; i < array.length; i++)
for (int j = i + 1; j < array.length; j++)
combinations.add(new Combination(array, i, j));
Then using this List of Combination you can compute the minimum distance among them all:
int min = combinations.stream()
.mapToInt(Combination::getDistance)
.min().getAsInt();
And finally, you can select those combinations that match the minimum distance previously computed:
combinations.stream()
.filter(c -> c.getDistance() == min)
.forEach(c -> System.out.println(c));
The key is having the Combination class abstracted away in its own encapsulated class, so it can be solely responsible of providing the necessary APIs to inspect a particular combination: indexes, values, distances, high value, low value and even String (toString) representations.
The following is a full working demo of this approach, run it to get a feeling for it:
import java.util.ArrayList;
import java.util.List;
public class MinimumDistance {
public static void main(String[] args) {
printMinimums(5, 50, 3, 42, 18, 16, 8, 30, 44);
}
public static void printMinimums(int... array) {
List<Combination> combinations = new ArrayList<>();
for (int i = 0; i < array.length; i++)
for (int j = i + 1; j < array.length; j++)
combinations.add(new Combination(array, i, j));
int min = combinations.stream()
.mapToInt(Combination::getDistance)
.min().getAsInt();
combinations.stream()
.filter(c -> c.getDistance() == min)
.forEach(c -> System.out.println(c));
}
static class Combination {
int indexA, indexB, valueA, valueB;
public Combination(int[] array, int indexA, int indexB) {
this.indexA = indexA;
this.indexB = indexB;
this.valueA = array[indexA];
this.valueB = array[indexB];
}
public int getDistance() {
return getHigh() - getLow();
}
public boolean isValueAHigh() {
return valueA > valueB;
}
public int getHigh() {
return isValueAHigh() ? valueA : valueB;
}
public int getLow() {
return isValueAHigh() ? valueB : valueA;
}
public int getHighIndex() {
return isValueAHigh() ? indexA : indexB;
}
public int getLowIndex() {
return isValueAHigh() ? indexB : indexA;
}
public String toString() {
return String.format("%d[%d] - %d[%d] = %d",
getHigh(), getHighIndex(),
getLow(), getLowIndex(),
getDistance());
}
}
}
Complete code on GitHub
Hope this helps.
I found this on the Internet. Are you doing this exercise?
Reference: https://www.geeksforgeeks.org/find-the-minimum-distance-between-two-numbers/
public class MinimumDistance {
int minDist(int arr[], int n, int x, int y)
{
int i, j;
int min_dist = Integer.MAX_VALUE;
for (i = 0; i < n; i++)
{
for (j = i + 1; j < n; j++)
{
if ((x == arr[i] && y == arr[j]
|| y == arr[i] && x == arr[j])
&& min_dist > Math.abs(i - j))
min_dist = Math.abs(i - j);
}
}
return min_dist;
}
public static void main(String[] args)
{
MinimumDistance min = new MinimumDistance();
int arr[] = {3, 5, 4, 2, 6, 5, 6, 6, 5, 4, 8, 3};
int n = arr.length;
int x = 3;
int y = 6;
System.out.println("Minimum distance between " + x + " and " + y
+ " is " + min.minDist(arr, n, x, y));
}
}
While iterating through your for loops, you could populate a Map of Integer distances to a List of indices Map<Integer,List<Integer>> (or even the actual values depending upon your use case). If you always add both indices to the List together, then you know they are always adjacent to one another in the List for later retrieval as pairs. Then just use your minimum distance as the key to the map to pull the list of adjacent pairs. Keep in mind that as described this list will have duplicates.
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 try to find duplicate number in array but i have one problem
if number in array that duplicated more than 2 number it will print like this
Dupicate number is :40
Dupicate number is :40
that not correct.
So, I just want to print only number that duplicate and how many they occur.
this my code below.
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
int[] x = {
10, 20, 30, 40, 40, 40, 25
};
int count = 0;
for (int i = 1; i < x.length; i++) {
if (x[i - 1] == x[i]) {
System.out.println("Dupicate number is :" + x[i]);
count++;
}
}
System.out.println(count);
}
Put the array members in an hashmap that keeps the count.
then iterate over the map. So you find also all duplicates.
public static void main(String[] args)
{
int[] x = { 10, 20, 30, 40, 40, 40, 25 };
Map<Integer, Integer> count = new HashMap<>();
for (int i = 1; i < x.length; i++) {
// if (count.containsKey(x[i]) && (x[i] == x[i-1]) ) {
// use this if the duplicates must be consecutive
if (count.containsKey(x[i])) {
count.put(x[i], count.get(x[i]) + 1);
} else {
count.put(x[i], 1);
}
}
for (Entry<Integer, Integer> entry : count.entrySet()) {
if (entry.getValue() > 1) {
System.out.println("Dupicate number is :" + entry.getKey() + " " + entry.getValue() + " occurences");
}
}
}
EDIT
Added in comments the modification for consecutive duplications, but this finds only the last duplicate
Use HashSet fro Java Util:
// x is name of your array
int[] x = {
3, 4, 4, 5, 6
};
HashSet < Integer > mySet = new HashSet < Integer > ();
ArrayList < Integer > dlist = new ArrayList < Integer > ();
for (int val: x) {
if (!mySet.add(val)) {
dlist.add(val);
}
}
for (int i = 0; i < dlist.size(); i++) {
System.out.println(dlist.get(i));
}
Now the newArr contains only non-repeated elements.
No. of duplicates = x.length - newArr.length
A practical solution would be using collections:
turn the array into a list,
the method Collections.frequency(a, b) will return how oft b is present in the collection a, so you need to iterate the list and then populate a map with the result of that method
Example:
public static void main(String[] args) {
int[] x = { 10, 20, 30, 40, 40, 40, 25 };
List<Integer> myInts = new ArrayList<Integer>();
for (int index = 0; index < x.length; index++) {
myInts.add(x[index]);
}
Map<Integer, Integer> ss = new HashMap<Integer, Integer>();
for (int index = 0; index < x.length; index++) {
if (Collections.frequency(myInts, x[index]) > 1) {
ss.put(x[index], Collections.frequency(myInts, x[index]));
}
}
System.out.println(ss);
}
that code will print
{40=3}
that is actually what you are looking for.