The goal is to have no duplicates in my Arraylist of Arraylist of Integers "listResults".
Here I iterate through a list of elements "listOfElements", and if the sum of two elements within this list is equal to the target, then I store indexes of both elements in an ArrayList "pair". Then I add that ArrayList to the list of ArrayList "listResults" and continue iterating.
At the end I might end up with listResults containing one or more arrayLists. However I don't want it to contain duplicates like [2,3] and [3,2] or [4,0] and [0,4]
int target = 60;
ArrayList<ArrayList<Integer>> listResults = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> listOfElements = new ArrayList<Integer>();
listOfElements.add(1);
listOfElements.add(10);
listOfElements.add(25);
listOfElements.add(35);
listOfElements.add(60);
for (int i = 0; i < listOfElements.size(); i++) {
for (int j = 0; j < listOfElements.size(); j++) {
if (listOfElements.get(i) + listOfElements.get(j) == target) {
ArrayList<Integer> pair = new ArrayList<Integer>();
pair.add(i);
pair.add(j);
listResults.add(pair);
}
}
}
System.out.println(listResults);
Based on the current code, the output is: [ [2,3] , [3,2] ] but this is not acceptable as [2,3] and [3,2] are duplicates. Only [2,3] should be allowed as it was the first one to be added to the ArrayList.
You shouldn't check the already visited elements. In your inner for-loop,
change
int j = 0;
to
int j = i + 1;
If the condition is true, use the break statement.
Related
List<List<Integer>> myList = new ArrayList<>(3);
for(int i=0; i < 3; i++) {
myList.add(new ArrayList());
}
myList.get(0).add(1); // 0,0
myList.get(0).add(4); //0,1
myList.get(1).add(2); // 1,0
myList.get(1).add(5); // 1,1
myList.get(2).add(3);// 2,0
myList.get(2).add(6); //2,1
myList.get(2).add(7); //2,3
for(int i =0; i<myList.get(i).size(); i++){
for(int j=0; j<myList.size(); j++){
System.out.println(myList.get(j).get(i));
}
}
I cant figure out how to iterate through the list on a index based, with different lengths on each list. My code above only works if all lists are the same size.
Ideal output would be:
1
2
3
4
5
6
7
But I cant figure out how to print out 7 since that list is a different length. This might be a very simple solution and ill probably feel dumb after. Thanks guys
To iterate over all elements of List of Lists you need to iterate in the first for-loop over the outer List, and in the second for-loop over the inner loop at that index. There are several possibilities to achieve the iteration over all elements, as you will see in the following examples.
(Your code would also produce a IndexOutOfBoundsException for the last entry).
Iterating through a List of Lists
Option 1 (your code corrected)
for (int i = 0; i < myList.size(); i++) { // i represents index of outer List
for (int j = 0; j < myList.get(i).size(); j++) { //j represents index of the inner list at index i
System.out.println(myList.get(i).get(j));
}
}
Option 2 (using for-each loop)
for (List<Integer> innerList : myList) {
for (Integer currentPosition : innerList) {
System.out.println(currentPosition);
}
}
Option 3 (using streams)
myList.stream()
.flatMap(Collection::stream)
.forEach(System.out::println);
}
Edit due to comment: added traverse method for wanted output
If you want to print out all first entries of the inner lists first, a possibility would be to traverse your List<List<Integer>> with a method like this (method is generic, would also work with other classes):
private static <T> List<List<T>> traverse(List<List<T>> input) {
List<List<T>> result = new ArrayList<>();
for (int i = 0; i < input.size(); i++) {
for (int j = 0; j < input.get(i).size(); j++) {
if(result.size() <= j) {
result.add(new ArrayList<>());
}
result.get(j).add(input.get(i).get(j));
}
}
return result;
}
In your method then just create a new List<List<Integer>> like this and iterate over this new list of lists:
List<List<Integer>> myListTraversed = traverse(myList);
I want to store unique lists, so I am using HashSet. But, I am not getting desired output. Here is my code, Could you tell me what is going wrong?
public List<List<Integer>> threeSum(int[] nums) {
Set<List<Integer>> res = new HashSet<>();
for(int i = 0; i< nums.length; i++){
int target = 0-nums[i];
Set<Integer> neg = new HashSet<>();
for(int j = i+1 ; j<nums.length; j++){
int rem = target - nums[j];
if(neg.contains(nums[j])){
res.add(new ArrayList<>(Arrays.asList(nums[i], rem, nums[j])));
}
else{
neg.add(rem);
}
}
}
System.out.println(res);
return new ArrayList<>(res);
}
Here my nums is [-1,0,1,2,-1,-4].
My output is [[-1,2,-1],[0,1,-1],[-1,0,1]]. Why am I getting both [0,1,-1] and [-1,0,1] into res as both contain the same elements. I what only one of these? What should I do?
From the Javadoc of List.equals:
Returns true if and only if the specified object is also a list, both lists have the same size, and all corresponding pairs of elements in the two lists are equal.
So, [0,1,-1] and [-1,0,1] aren't equal, despite containing the same elements, because they aren't in the same order.
The easiest way to solve this would be to sort the list:
res.add(Stream.of(nums[i], rem, nums[j]).sorted().collect(toList()));
You can sort the List before adding to the Set so they will be in the same order.
am trying to split elements in array list .
For example i have an arrayList like
List <String> elements = new ArrayList<String>();
elements // ["frnec","fdct","logic","mastro","seloger"]
The size of the elements should be dynamic...
List<List<String>> splittedlists = null;
i want to split the elements like ["frnec"] ,["fdct",logic"],["mastro", "seloger"].
splittedlists //[["frnec"] ,["fdct",logic"],["mastro", "seloger"]].
But the size of the new splittedlists should not exceed 4 ,based on that i have to chop the elements
i had got lots of code code to split lists.But i dont know how to set the maximum size of the 'splittedlists'.
but it will split by setting the target size of spitted elements
public static <T extends Object> List<List<T>> split(List<T> list, int targetSize) {
List<List<T>> lists = new ArrayList<List<T>>();
for (int i = 0; i < list.size(); i += targetSize) {
lists.add(list.subList(i, Math.min(i + targetSize, list.size())));
}
return lists;
}
My requirmeent is to split elements in the list by setting the maximum array size(here 4) of splittedlists
If elements are // ["frnec","fdct"] i want to split is as ["frnec"], ["fdct"]
if elements are // [0, 1, 2, 3, 4, 8, 6] i have to split without exceeding the new array size 4 like
[[0,1],[2,3],[4,8],[6]]
Here is my answer.. Guess you can understand what I'm doing..
List<String> list = new ArrayList<>();
for (int i = 1; i < 11; i++) {
list.add(i+"");
}
List<List<String>> lists = new ArrayList<>();
int x = list.size()/4;
int y = list.size()%4;
int j = 0;
for (int i = 0; i < list.size(); i=j) {
j = i+x;
if(y>0){
j++;
y--;
}
lists.add(list.subList(i, j));
}
System.out.println(list);
System.out.println(lists);
If you don't need to maintain the order you can use modulus (%) operator. So for 3 sublists, it would put the 0th element in the 0th sublist, the first element in the first sublist, the second element in the second sublist, the third element in the 0th sublist, the fourth element in the 1st sublist.... etc.
Something like:
for(int i = 0; i < list.size() ; i++){
listOfLists.get(i % 3).add(list.get(i));
}
I need to merge two lists into one, in ascending order, not duplicates, and I think my code is really close, I'm just missing something and I can't figure it out. As of now, my code is not working properly in my merge method. I think it has something to do with my loops, but I just can't work around it. My current method prints the new list, but it is not in perfect increasing order. I would appreciate any assistance in figuring out how to make this method print my merged list with ascending order using the contents of l1 and l2.
**Note: I cannot use any built-in array sorting methods.
Thanks!
import java.util.ArrayList;
import java.util.Random;
public class MergeLists {
public static ArrayList<Integer> merge(ArrayList<Integer> l1, ArrayList<Integer> l2){
ArrayList<Integer> mergedList = new ArrayList();
for (int j = 0; j < l1.size(); j++) {
if (l1.get(j) < l2.get(j)) {
mergedList.add(l1.get(j));
mergedList.add(l2.get(j));
} else {
mergedList.add(l2.get(j));
mergedList.add(l1.get(j));
}
}
for (int i = l2.size() - l1.size(); i < l2.size(); i++) {
mergedList.add(l2.get(i));
}
return mergedList;
}
public static ArrayList<Integer> makeRandomIncreasingList(int length) {
ArrayList<Integer> randomList = new ArrayList();
Random rand = new Random();
int inList = rand.nextInt(9) + 1;
int inList2 = rand.nextInt(9) + 1;
for (int i = 0; i < length; i++) {
randomList.add(inList);
inList = inList + inList2;
}
return randomList;
}
public static void doMergeTest() {
ArrayList<Integer> list1 = makeRandomIncreasingList(10);
ArrayList<Integer> list2 = makeRandomIncreasingList(20);
ArrayList<Integer> mergedList = merge(list1, list2);
System.out.println("List 1:" + list1);
System.out.println("List 2:" + list2);
System.out.println("Merged list:" + mergedList);
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
System.out.println("Performing merge test #" + (i + 1) + ":");
doMergeTest();
}
}
}
Remove duplicates
arrayList1.remove(arrayList2);
Then merge two arrayList:
arrayList1.addAll(arrayList2);
And Lastly sort the last
collections.sort(arrayList1);
Another way is to use SET: Set doesnt allow duplicates
(HashSet is faster depending on the List implementation class)
Set setmerge = new HashSet(list1);
setmerge.addAll(list2);
list1.clear();
list1.addAll(setmerge);
The first part of your merge() method seems ok, if you modify it a little bit. You need to be going through both lists in parallel, something like
int i = 0, j = 0;
for (; i < l1.size() && j < l2.size();)
And compare individual items and increment indices independently, as in
if (l1.get(i) < l2.get(j)) {
...
i++;
} else
...
j++;
}
The way you were doing it you were literally going in parallel, which is not always correct (think of lists [1 2 2] and [1 1 1] => your merge would look like [1 1 1 2 1 2])
Then, after your "parallel" for-loop (the one where you're iterating through both lists), one of your indices is always going to break your loop because it's at the end of its list. For in-order merging, I usually declare i, j outside the loop (you'll need then after your first for-loop, like above) and then do something like (in your notation):
for (int i1 = i; i1 < l1.size(); i1++) {
mergeList.add(l1.get(i1));
}
for (int i2 = j; i2 < l2.size(); i2++) {
mergeList.add(l2.get(i2));
}
After your first for-loop, you get to the end of exactly one of the lists (someone's going to break the loop), so exactly one of the above loops is going to get executed, and that will contain the remaining items, in order.
Edit: your last for-loop of the merge() method is not correct for your purpose.
You have assumed l2 items are always bigger than l1 items, since you are adding remainder of l2 items in the end of the list. You need to compare them with mergedList items and add them accordingly.
I created an ArrayList of 80 Arraylists. Each ArrayList inside, has the values 1-9.
However, when I delete a value from one of the Arraylists its deleted in all of them.
ArrayList<List> available = new ArrayList<List>();
ArrayList<Integer> possibleValues = new ArrayList<Integer>();
for(int j = 1; j<=9; j++){
possibleValues.add(j);
}
for (int i = 0; i<=80; i++){
available.add(possibleValues);
}
int b = (int) available.get(0).get(2);
available.get(0).remove(0);
String s = available.get(80).toString();
System.out.println(" " + s);
}
Any help is appreciated.
The problem here is that you've added the same ArrayList possibleValues to available 81 times. So, the available list contains 81 references to the same possibleValues list.
Any changes made to the list are visible through any of those 81 references.
If you don't want the changes visible to all references, just one, then you need to make 81 copies of the list to add:
for (int i = 0; i<=80; i++){
available.add(new ArrayList<Integer>(possibleValues));
}
That's because you're adding the same ArrayList to every index of the outer ArrayList . Any change to this ArrayList will automatically result in a change in the other ArrayList .
Nest your loops to always create a new ArrayList or construct a new ArrayList from the already existing one.
Because you are adding the values to same ArrayList. You need to create new Arraylist for 0 to 80 iterations.
for(int j = 1; j<=9; j++){
possibleValues.add(j);// one ArrayList with values.
}
for (int i = 0; i<=80; i++){
available.add(possibleValues); //Here adding same Arraylist 80 times.
}
Try this one
ArrayList<List> available = new ArrayList<List>();
ArrayList<Integer> possibleValues = new ArrayList<Integer>();
for (int i = 0; i<=80; i++){
possibleValues = new ArrayList<Integer>();
for(int j = 1; j<=9; j++){
possibleValues.add(j);
}
available.add(possibleValues);
}
You are adding the same ArrayList 81 times. ArrayList is a reference type, so any change to it will affect all items. It should be:
available.add(new ArrayList(possibleValues));