Java List looping based of available size - java

I want to display only 12 sorted elements from myList. If the size is less than 12, say 5, or 3, or 1, still I need to loop and display only those available items.
Below is my code:
public class JavaApplication {
public static void main(String[] args) {
List<String> myList = new ArrayList<>();
myList.add("20150830");
myList.add("20141201");
myList.add("20150716");
myList.add("20151131");
myList.add("20141101");
myList.add("20150620");
myList.add("20150301");
myList.add("20150702");
myList.add("20150511");
Collections.sort(myList,Collections.reverseOrder());
for(int i = 0; i < myList.size(); i++) {
System.out.println(myList.get(i).toString());
}
}
}

This is a good use-case for streams.
myList.stream()
.sorted(Comparator.<String>reverseOrder())
.limit(12)
.forEach(System.out::println);

Just add one more condition in your loop to restrict the loop for 12.
for(int i = 0; i < myList.size() && i < 12 ; i++){
System.out.println(myList.get(i).toString());
}

You can try:
int maxValuesToDisplay=12;
int maxToIterate=(myList.size()<maxValuesToDisplay) ? myList.size() : maxValuesToDisplay;
for(int i = 0; i < maxToIterate; i++){
System.out.println(myList.get(i).toString());
}

Use List.subList(int fromIndex, int toIndex);
public class JavaApplication {
public static void main(String[] args) {
List<String> myList = new ArrayList<>();
myList.add("20150830");
myList.add("20141201");
myList.add("20150716");
myList.add("20151131");
myList.add("20141101");
myList.add("20150620");
myList.add("20150301");
myList.add("20150702");
myList.add("20150511");
Collections.sort(myList,Collections.reverseOrder());
int a = myList.size();
List subList = null;
if(a<12)
subList = myList.subList(0,a);
else subList = myList.subList(0,12);
//Print sublist now
}
}

You could use the Math.min() function and iterate the minimum of 12 and the list-size.
for(int i = 0; i < Math.min(myList.size(), 12); i++){
System.out.println(myList.get(i).toString());
}

You can use TreeSet :
public static void main(String[] args) {
Set<String> myList = new TreeSet<>();
myList.add("20150830");
myList.add("20141201");
myList.add("20150716");
myList.add("20151131");
myList.add("20141101");
myList.add("20150620");
myList.add("20150301");
myList.add("20150702");
myList.add("20150511");
int i = 0;
for(String s : myList){
System.out.println(s);
i++;
if(i >= 5) {
break;
}
}
}
And for reverse order :
public static void main(String[] args) {
TreeSet<String> myList = new TreeSet<>();
myList.add("20150830");
myList.add("20141201");
myList.add("20150716");
myList.add("20151131");
myList.add("20141101");
myList.add("20150620");
myList.add("20150301");
myList.add("20150702");
myList.add("20150511");
Iterator<String> it = myList.descendingIterator();
int i = 0;
while(it.hasNext()) {
String s = it.next();
System.out.println(s);
i++;
if (i >= 5) {
break;
}
}
}

Related

Modify the java program so that it works for the numbers in range between -25 and 25

I've started learning java some time ago. I'm reading through the Java Foundations book and doing exercises from the book to practice.
Just come across this one "Modify the java program so that it works for the numbers in the range between -25 and 25." and I wonder if you have any different solutions to it or is it really that simple? :)
Here's the original code:
public class BasicArray
{
public static void main(String[] args)
{
final int LIMIT = 15;
final int MULTIPLE = 10;
int[] list = new int[LIMIT];
// Initialize the array values
for(int index = 0; index < LIMIT; index++)
list[index] = index * MULTIPLE;
list[5] = 999; // change one array value
// Print the array values
for(int value : list)
System.out.println(value + "");
}
}
And here's my solution to it:
public class BasicArray
{
public static void main(String[] args)
{
final int LIMIT = 51;
final int MULTIPLE = 1;
int[] list = new int[LIMIT];
// Initialize the array values
for(int index = 0; index < LIMIT; index++)
list[index] = (index - 25) * MULTIPLE;
list[5] = 999; // change one array value
// Print the array values
for(int value : list)
System.out.println(value + "");
}
}
Yes, basically it's really simple exercise.
Regarding to your solution we actually don't need MULTIPLE in code.
public class BasicArray {
public static void main(String[] args) {
final int LIMIT = 51;
int[] list = new int[LIMIT];
// Initialize the array values
for(int index = 0; index < LIMIT; index++) {
list[index] = (index - 25);
}
list[5] = 999; // change one array value
// Print the array values
for(int value : list) {
System.out.println(value + "");
}
}
}
If you are ready for a bit of advanced java, you can try following:
public class BasicArray {
public static void main(String[] args) {
IntStream.rangeClosed(-25, 25)
.forEach(System.out::println);
}
}
Or this if you need to replace one value:
public class BasicArray {
public static void main(String[] args) {
IntStream.rangeClosed(-25, 25)
.forEach(i -> {
if (i == -20) { // change one array value
System.out.println(999);
} else {
System.out.println(i);
}
});
}
}

How to save permutation in a Set Java

I have this method that prints my permutations of a Set I'm giving with my parameters. But I need to save them in 2 separate sets and compare them. So, for instance I have [5,6,3,1] and [5,6,1,3], by adding them in two separate BST, I can compare them by using the compareTo function to check whether their level order is the same. But I am having trouble with saving these permutations from my method into a set in my main. Does anyone know how to save these into a set?
What I have now:
import edu.princeton.cs.algs4.BST;
import java.util.*;
public class MyBST {
public static void main(String[] args) {
int size = 4;
BST<Integer, Integer> bst1 = new BST<Integer, Integer>();
BST<Integer, Integer> bst2 = new BST<Integer, Integer>();
Random r = new Random();
Set<Integer> tes = new LinkedHashSet<>(size);
Stack<Integer> stack = new Stack<>();
while (tes.size() < size) {
tes.add(r.nextInt(10));
}
System.out.println(tes);
System.out.println("possible combinations");
Iterator<Integer> it = tes.iterator();
for (int i = 0; i < tes.toArray().length; i++) {
Integer key = it.next();
bst1.put(key, 0);
}
combos(tes, stack, tes.size());
}
}
and here is the method I use:
public static void combos(Set<Integer> items, Stack<Integer> stack, int size) {
if (stack.size() == size) {
System.out.println(stack);
}
Integer[] itemz = items.toArray(new Integer[0]);
for (Integer i : itemz) {
stack.push(i);
items.remove(i);
combos(items, stack, size);
items.add(stack.pop());
}
}
And this is the output:
I'm not sure if I understood your idea but maybe this will help:
Yours combos method will return set of all permutations (as Stacks)
...
for (int i = 0; i < tes.toArray().length; i++) {
Integer key = it.next();
bst1.put(key, 0);
}
Set<Stack<Integer>> combos = combos(tes, stack, tes.size()); //there you have set with all Stacks
}
}
public static Set<Stack<Integer>> combos(Set<Integer> items, Stack<Integer> stack, int size) {
Set<Stack<Integer>> set = new HashSet<>();
if(stack.size() == size) {
System.out.println(stack.to);
set.add((Stack) stack.clone());
}
Integer[] itemz = items.toArray(new Integer[0]);
for(Integer i : itemz) {
stack.push(i);
items.remove(i);
set.addAll(combos(items, stack, size));
items.add(stack.pop());
}
return set;
}

[Hackerrank][Performance Improvement] Similar Destinations

I am currently solving a challenge that I found on Hackerrank and am in need of some assistance in the code optimization/performance department. I've managed to get my code working and returning the right results but it is failing at the final test case with a timeout error. The input is quite large so, that explains why the code is taking longer that expected.
Problem statement: Similar Destinations
I've attempted to think of different ways of pruning my (intermediate) result set but could not come up with something that I did not already have. I believe that the find function could use a bit more tweaking. I've tried my best to reduce the number of paths that the recursive function has to take but ultimately, it has to look at every destination in order to come up with the right results. However, I did terminate a recursive path if the number of tags in common between destinations were below the min limit. Is there anything else that I could do here?
My code is as follows:-
static class Destination {
String dest;
List<String> tags;
public Destination(String dest, List<String> tags) {
this.dest = dest;
this.tags = tags;
}
#Override
public String toString() {
return dest;
}
}
static List<Destination> allDest = new ArrayList<Destination>();
static int min;
static Set<String> keysTracker = new HashSet<String>();
static Set<String> tagsTracker = new HashSet<String>();
static Map<String, List<String>> keysAndTags = new HashMap<String, List<String>>();
static void find(List<String> commonKey, List<String> commonTags, int index) {
if (index >= allDest.size())
return;
if (commonTags.size() < min)
return;
if (tagsTracker.contains(commonTags.toString()) || keysTracker.contains(commonKey.toString())) {
return;
}
String dest = allDest.get(index).dest;
commonKey.add(dest);
for (int i = index + 1; i < allDest.size(); ++i) {
List<String> tempKeys = new ArrayList<String>(commonKey);
List<String> tags = allDest.get(i).tags;
List<String> tempTags = new ArrayList<String>(commonTags);
tempTags.retainAll(tags);
find(tempKeys, tempTags, i);
if (tempTags.size() >= min) {
if (!tagsTracker.contains(tempTags.toString())
&& !keysTracker.contains(tempKeys.toString())) {
tagsTracker.add(tempTags.toString());
keysTracker.add(tempKeys.toString());
StringBuilder sb = new StringBuilder();
for (int j = 0; j < tempKeys.size(); ++j) {
sb.append(tempKeys.get(j));
if (j + 1 < tempKeys.size())
sb.append(",");
}
keysAndTags.put(sb.toString(), tempTags);
}
}
}
}
public static void main(String[] args) {
init();
sort();
calculate();
answer();
}
static void init() {
Scanner s = new Scanner(System.in);
min = s.nextInt();
s.nextLine();
String line;
while (s.hasNextLine()) {
line = s.nextLine();
if (line.isEmpty())
break;
String[] tokens = line.split(":");
String dest = tokens[0];
tokens = tokens[1].split(",");
List<String> tags = new ArrayList<String>();
for (int j = 0; j < tokens.length; ++j)
tags.add(tokens[j]);
Collections.sort(tags);
Destination d = new Destination(dest, tags);
allDest.add(d);
}
s.close();
}
static void sort() {
Collections.sort(allDest, new Comparator<Destination>() {
#Override
public int compare(Destination d1, Destination d2) {
return d1.dest.compareTo(d2.dest);
}
});
}
static void calculate() {
for (int i = 0; i < allDest.size() - 1; ++i) {
find(new ArrayList<String>(), new ArrayList<String>(allDest.get(i).tags), i);
}
}
static void answer() {
List<Map.Entry<String, List<String>>> mapInListForm = sortAnswer();
for (Map.Entry<String, List<String>> entry : mapInListForm) {
System.out.print(entry.getKey() + ":");
for (int i = 0; i < entry.getValue().size(); ++i) {
System.out.print(entry.getValue().get(i));
if (i + 1 < entry.getValue().size())
System.out.print(",");
}
System.out.println();
}
}
static List<Map.Entry<String, List<String>>> sortAnswer() {
List<Map.Entry<String, List<String>>> mapInListForm =
new LinkedList<Map.Entry<String, List<String>>>(keysAndTags.entrySet());
Collections.sort(mapInListForm, new Comparator<Map.Entry<String, List<String>>>() {
public int compare(Map.Entry<String, List<String>> e1, Map.Entry<String, List<String>> e2) {
if (e1.getValue().size() > e2.getValue().size()) {
return -1;
} else if (e1.getValue().size() < e2.getValue().size()) {
return 1;
}
return e1.getKey().compareTo(e2.getKey());
}
});
return mapInListForm;
}
Any help is greatly appreciated. Thanks!
I've managed to solve the problem after a bit of selective profiling. It would seem that my initial hunch was right. The problem had less to do with the algorithm and more towards the data structures that I was using! The culprit was in the find method. Specifically, when calling the retainAll method on two lists. I had forgotten the that it would take O(n^2) time to iterate through two lists. That was why it was slow. I then changed list into a HashSet instead. As most of us know, a HashSet has an O(1) time complexity when it comes to accessing its values. The retainAll method stayed but instead of finding the intersection between two lists, we now find the intersection between two sets instead! That managed to shave off a couple of seconds off of the total elapsed runtime and all the tests passed. :)
The find method now looks like this:-
static void find(List<String> commonKey, List<String> commonTags, int index) {
if (index >= allDest.size())
return;
if (commonTags.size() < min)
return;
if (tagsTracker.contains(commonTags.toString()) || keysTracker.contains(commonKey.toString())) {
return;
}
String dest = allDest.get(index).dest;
commonKey.add(dest);
for (int i = index + 1; i < allDest.size(); ++i) {
List<String> tempKeys = new ArrayList<String>(commonKey);
List<String> tags = allDest.get(i).tags;
Set<String> tempTagsSet1 = new HashSet<String>(commonTags);
Set<String> tempTagsSet2 = new HashSet<String>(tags);
tempTagsSet1.retainAll(tempTagsSet2);
List<String> tempTags = new ArrayList<String>(tempTagsSet1);
if (tempTags.size() >= min)
Collections.sort(tempTags);
find(tempKeys, tempTags, i);
if (tempTags.size() >= min) {
if (!tagsTracker.contains(tempTags.toString())
&& !keysTracker.contains(tempKeys.toString())) {
tagsTracker.add(tempTags.toString());
keysTracker.add(tempKeys.toString());
StringBuilder sb = new StringBuilder();
for (int j = 0; j < tempKeys.size(); ++j) {
sb.append(tempKeys.get(j));
if (j + 1 < tempKeys.size())
sb.append(",");
}
keysAndTags.put(sb.toString(), tempTags);
}
}
}
}

Partition a Set into smaller Subsets and process as batch

I have a continuous running thread in my application, which consists of a HashSet to store all the symbols inside the application. As per the design at the time it was written, inside the thread's while true condition it will iterate the HashSet continuously, and update the database for all the symbols contained inside HashSet.
The maximum number of symbols that might be present inside the HashSet will be around 6000. I don't want to update the DB with all the 6000 symbols at once, but divide this HashSet into different subsets of 500 each (12 sets) and execute each subset individually and have a thread sleep after each subset for 15 minutes, so that I can reduce the pressure on the database.
This is my code (sample code snippet)
How can I partition a set into smaller subsets and process (I have seen the examples for partitioning ArrayList, TreeSet, but didn't find any example related to HashSet)
package com.ubsc.rewji.threads;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.PriorityBlockingQueue;
public class TaskerThread extends Thread {
private PriorityBlockingQueue<String> priorityBlocking = new PriorityBlockingQueue<String>();
String symbols[] = new String[] { "One", "Two", "Three", "Four" };
Set<String> allSymbolsSet = Collections
.synchronizedSet(new HashSet<String>(Arrays.asList(symbols)));
public void addsymbols(String commaDelimSymbolsList) {
if (commaDelimSymbolsList != null) {
String[] symAr = commaDelimSymbolsList.split(",");
for (int i = 0; i < symAr.length; i++) {
priorityBlocking.add(symAr[i]);
}
}
}
public void run() {
while (true) {
try {
while (priorityBlocking.peek() != null) {
String symbol = priorityBlocking.poll();
allSymbolsSet.add(symbol);
}
Iterator<String> ite = allSymbolsSet.iterator();
System.out.println("=======================");
while (ite.hasNext()) {
String symbol = ite.next();
if (symbol != null && symbol.trim().length() > 0) {
try {
updateDB(symbol);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void updateDB(String symbol) {
System.out.println("THE SYMBOL BEING UPDATED IS" + " " + symbol);
}
public static void main(String args[]) {
TaskerThread taskThread = new TaskerThread();
taskThread.start();
String commaDelimSymbolsList = "ONVO,HJI,HYU,SD,F,SDF,ASA,TRET,TRE,JHG,RWE,XCX,WQE,KLJK,XCZ";
taskThread.addsymbols(commaDelimSymbolsList);
}
}
With Guava:
for (List<String> partition : Iterables.partition(yourSet, 500)) {
// ... handle partition ...
}
Or Apache Commons:
for (List<String> partition : ListUtils.partition(yourList, 500)) {
// ... handle partition ...
}
Do something like
private static final int PARTITIONS_COUNT = 12;
List<Set<Type>> theSets = new ArrayList<Set<Type>>(PARTITIONS_COUNT);
for (int i = 0; i < PARTITIONS_COUNT; i++) {
theSets.add(new HashSet<Type>());
}
int index = 0;
for (Type object : originalSet) {
theSets.get(index++ % PARTITIONS_COUNT).add(object);
}
Now you have partitioned the originalSet into 12 other HashSets.
We can use the following approach to divide a Set.
We will get the output as
[a, b]
[c, d]
[e]`
private static List<Set<String>> partitionSet(Set<String> set, int partitionSize)
{
List<Set<String>> list = new ArrayList<>();
int setSize = set.size();
Iterator iterator = set.iterator();
while(iterator.hasNext())
{
Set newSet = new HashSet();
for(int j = 0; j < partitionSize && iterator.hasNext(); j++)
{
String s = (String)iterator.next();
newSet.add(s);
}
list.add(newSet);
}
return list;
}
public static void main(String[] args)
{
Set<String> set = new HashSet<>();
set.add("a");
set.add("b");
set.add("c");
set.add("d");
set.add("e");
int size = 2;
List<Set<String>> list = partitionSet(set, 2);
for(int i = 0; i < list.size(); i++)
{
Set<String> s = list.get(i);
System.out.println(s);
}
}
If you are not worried much about space complexity, you can do like this in a clean way :
List<List<T>> partitionList = Lists.partition(new ArrayList<>(inputSet), PARTITION_SIZE);
List<Set<T>> partitionSet = partitionList.stream().map((Function<List<T>, HashSet>) HashSet::new).collect(Collectors.toList());
The Guava solution from #Andrey_chaschev seems the best, but in case it is not possible to use it, I believe the following would help
public static List<Set<String>> partition(Set<String> set, int chunk) {
if(set == null || set.isEmpty() || chunk < 1)
return new ArrayList<>();
List<Set<String>> partitionedList = new ArrayList<>();
double loopsize = Math.ceil((double) set.size() / (double) chunk);
for(int i =0; i < loopsize; i++) {
partitionedList.add(set.stream().skip((long)i * chunk).limit(chunk).collect(Collectors.toSet()));
}
return partitionedList;
}
A very simple way for your actual problem would be to change your code as follows:
Iterator<String> ite = allSymbolsSet.iterator();
System.out.println("=======================");
int i = 500;
while ((--i > 0) && ite.hasNext()) {
A general method would be to use the iterator to take the elements out one by one in a simple loop:
int i = 500;
while ((--i > 0) && ite.hasNext()) {
sublist.add(ite.next());
ite.remove();
}

Given a target sum, find if there is a pair of element in the given array which sums up to it

import java.util.HashMap;
public class target
{
public static void hash(int []a,int sum)
{
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
int i;
for (i = 0; i < a.length; ++i)
map.put(a[i], sum-a[i]);
for (i = 0; i < a.length; ++i)
if(map.containsValue(a[i]) && map.get(a[i])!=null)
{
System.out.println("("+a[i]+","+map.get(a[i])+")");
map.remove(a[i]);
}
}
public static void main(String[] args)
{
int []a={1, 2, 13, 34, 9, 3, 23, 45, 8, 7, 8, 3, 2};
hash(a,11);
}
}
I want to know if there is a better and more efficient solution that the above one. Complexity of this is n. Can I do better?
Your implementation misses duplicated pairs.
You could
sort the array
iterate from the start and for each element
calculate the required complement (sum - element)
do a reverse binary search (from the end of the sorted array) looking for that precise value
if found, remove both
It boils down to the observation that, with elements sorted:
n1 < n2 < n3 < n4 < n5 < n6
the most likely pairs are coming symmetrically from both ends to the middle. Now, the worst case is still bad, but at least you don't have the hashtable overhead
As I commented, your sollution is not O(N), because the containsValue make a search of all values stored at the HashMap. To solve it, I made a different approach using your solution:
public static void newVersion(int[] a, int sum){
HashMap<Integer, Boolean> map = new HashMap<Integer, Boolean>();
for (int i= 0; i< a.length; i++) {
map.put(sum - a[i], true);
}
for (int i = 0; i < a.length; i++) {
if (map.containsKey(a[i]) && map.get(a[i])) {
System.out.println("("+(sum-a[i])+","+a[i]+")");
map.put(a[i], false);
map.put(sum-a[i], false);
}
}
}
At the first step, it stores the "complement value" of each integer and at the second step it checks if the complement exists. If it exists, mark both pair as used.
This complexity is:
* O(N) for the first looping
* O(N) * (O(1) + O(1)) for the second loop and the containsValue and get.
* Finally: O(N) + O(N) .:. O(N) solution,
I have the following solution for this problem. The time complexity should be O(N) because the HashMap operations put, get and keySet are O(1).
import java.util.HashMap;
import java.util.Map;
/**
* Find a pair of numbers in an array given a target sum
*
*
*/
public class FindNums {
public static void findSumsForTarget(int[] input, int target)
{
// just print it instead of returning
Map<Integer, String> myMap = populateMap(input);
// iterate over key set
for (Integer currKey : myMap.keySet()) {
// find the diff
Integer diff = target - currKey;
// check if diff exists in the map
String diffMapValue = myMap.get(diff);
if(diffMapValue!=null)
{
// sum exists
String output = "Sum of parts for target " + target + " are " + currKey + " and " + diff;
System.out.println(output);
return; // exit; we're done - unless we wanted all the possible pairs and permutations
}
// else
// keep looking
}
System.out.println("No matches found!");
}
private static Map<Integer, String> populateMap(int[] input)
{
Map<Integer,String> myMap = new HashMap<Integer,String>();
for (int i = 0; i < input.length; i++) {
String currInputVal = myMap.get(input[i]);
if(currInputVal!=null) // value already exists
{
// append current index location to value
currInputVal = currInputVal + ", " + i;
// do a put with the updated value
myMap.put(input[i], currInputVal);
}
else
{
myMap.put(input[i], Integer.toString(i)); // first argument is autoboxed to Integer class
}
}
return myMap;
}
// test it out!
public static void main(String[] args)
{
int[] input1 = {2,3,8,12,1,4,7,3,8,22};
int[] input2 = {1,2,3,4,5,6,7,8,9,10};
int[] input3 = {2,-3,8,12,1,4,7,3,8,22};
int target1 = 19;
int target2 = 16;
// test
FindNums.findSumsForTarget(input1, target1);
FindNums.findSumsForTarget(input1, -1);
FindNums.findSumsForTarget(input2, target2);
FindNums.findSumsForTarget(input3, target1);
}
}
import java.util.*;
import java.io.*;
class hashsum
{
public static void main(String arg[])throws IOException
{
HashMap h1=new HashMap();
h1.put("1st",new Integer(10));
h1.put("2nd",new Integer(24));
h1.put("3rd",new Integer(12));
h1.put("4th",new Integer(9));
h1.put("5th",new Integer(43));
h1.put("6th",new Integer(13));
h1.put("7th",new Integer(5));
h1.put("8th",new Integer(32));
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter no.");
int no=Integer.parseInt(br.readLine());
Iterator i=h1.entrySet().iterator();
boolean flag=false;
while(i.hasNext())
{
Map.Entry e1=(Map.Entry)i.next();
Integer n1=(Integer)e1.getValue();
Iterator j=h1.entrySet().iterator();
while(j.hasNext())
{
Map.Entry e2=(Map.Entry)j.next();
Integer n2=(Integer)e2.getValue();
if(no==(n1+n2))
{
System.out.println("Pair of elements:"+n1 +" "+n2);
flag=true;
}
}
}
if(flag==false)
System.out.println("No pairs");
}
}
public static void hash1(int[] a, int num) {
Arrays.sort(a);
// printArray(a);
int top = 0;
int bott = a.length - 1;
while (top < bott) {
while (a[bott] > num)
bott--;
int sum = a[top] + a[bott];
if (sum == num) {
System.out.println("Pair " + a[top] + " " + a[bott]);
top++;
bott--;
}
if (sum < num)
top++;
if (sum > num)
bott--;
}
}
Solution: O(n) time and O(log(n)) space.
public static boolean array_find(Integer[] a, int X)
{
boolean[] b = new boolean[X];
int i;
for (i=0;i<a.length;i++){
int temp = X-a[i];
if(temp >= 0 && temp < X) //make sure you are in the bound or b
b[temp]=true;
}
for (i=0;i<a.length;i++)
if(a[i]<X && b[a[i]]) return true;
return false;
}
Recursively to find the subset whose sum is the targeted sum from given array.
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Main {
public static Set<List<Integer>> set = new HashSet<>();
public static void main(String[] args) {
int[] biggerArray = {1, 2, 1, 1};
int targetedSum = 3;
findSubset(biggerArray, targetedSum);
}
public static void findSubset(int[] biggerArray, int targetedSum) {
for (int i = 0; i < biggerArray.length; i++) {
List<Integer> subset = new ArrayList<>();
if (biggerArray[i] > targetedSum)
continue;
else
subset.add(biggerArray[i]);
if (i + 1 < biggerArray.length)
find(subset, i, biggerArray, targetedSum, i);
}
System.out.println(set);
}
public static List<Integer> find(List<Integer> subset, int startIndex, final int[] biggerArray, final int targetedSum, final int skipIndex) {
if (skipIndex == startIndex) {
find(subset, startIndex + 1, biggerArray, targetedSum, skipIndex);
return null;
}
int subsetSum = findSumOfList(subset);
int remainedSum = targetedSum - subsetSum;
int i = startIndex;
if (remainedSum == 0) {
set.add(subset);
return null;
}
if ((startIndex < biggerArray.length) && (biggerArray[startIndex] == remainedSum)) {
List<Integer> temp = new ArrayList<Integer>(subset);
temp.add(biggerArray[i]);
set.add(temp);
}
else if ((startIndex < biggerArray.length) && (biggerArray[startIndex] < remainedSum)) {
while (i + 1 <= biggerArray.length) {
List<Integer> temp = new ArrayList<Integer>(subset);
if (i != skipIndex) {
temp.add(biggerArray[i]);
find(temp, ++i, biggerArray, targetedSum, skipIndex);
}
else {
i = i + 1;
}
}
}
else if ((startIndex < biggerArray.length) && (biggerArray[startIndex] > remainedSum)) {
find(subset, ++i, biggerArray, targetedSum, skipIndex);
}
return null;
}
public static int findSumOfList(List<Integer> list) {
int i = 0;
for (int j : list) {
i = i + j;
}
return i;
}
}
We need not have two for loops. The match can be detected in the same loop while populating the map it self.
public static void matchingTargetSumPair(int[] input, int target){
Map<Integer, Integer> targetMap = new HashMap<Integer, Integer>();
for(int i=0; i<input.length; i++){
targetMap.put(input[i],target - input[i]);
if(targetMap.containsKey(target - input[i])){
System.out.println("Mathcing Pair: "+(target - input[i])+" , "+input[i]);
}
}
}
public static void main(String[] args) {
int[] targetInput = {1,2,4,5,8,12};
int target = 9;
matchingTargetSumPair(targetInput, target);
}
We can easily find if any pair exists while populating the array itself. Use a hashmap and for every input element, check if sum-input difference element exists in the hashmap or not.
import java.util.*;
class findElementPairSum{
public static void main(String[] args){
Map<Integer, Integer> hm = new HashMap<Integer, Integer>();
Scanner sc = new Scanner(System.in);
System.out.println("Enter the sum key: ");
int sum=sc.nextInt();
for(int i=0; i<10; i++){
int x = sc.nextInt();
if(!hm.containsKey(sum-x)){
hm.put(x, 1);
} else {
System.out.println("Array contains two elements with sum equals to: "+sum);
break;
}
}
}
}

Categories

Resources