LinkedList Iteration - java

I'm new to coding and I'm trying to Iterate a linkedlist. The below is the question: Create a Linkedlist having elements ranging from 1 to 8. I need to reverse the list but with one condition i.e., if the num is given as 2. The output should be produced in the following way: [2,1,4,3,6,5,8,7].
Please find the code below. I tried and able to get the respective answer if num is either 2 or 4.
LinkedList<Integer> list = new LinkedList<>();
for (int i = 1; i < 9; i++) {
list.add(i);
}
int n = 2;
LinkedList<Integer> outList = new LinkedList<>();
while(list.size()>0) {
for(int i=n-1;i>=0;i--) {
outList.add(list.get(i));
list.remove(i);
}
}
System.out.println(outList);
I don't know whether this is the appropriate way. Please help me with the appropriate solution.
The problem I'm facing is if I give num as 3. I'm getting IndexOutOfBoundsException as there are only 2 elements in the last iteration.
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
at java.base/java.util.LinkedList.checkElementIndex(LinkedList.java:559)
at java.base/java.util.LinkedList.get(LinkedList.java:480)
at com.src.User.main(User.java:21)

In your solution, issue would be with last inner iteration. Each iteration is reversal of a block of n elements where as the last step it can be less than n. To consider this, min(n-1,list.size()-1) can be used.
LinkedList<Integer> list = new LinkedList<>();
for (int i = 1; i < 9; i++) {
list.add(i);
}
int n = 4;
LinkedList<Integer> outList = new LinkedList<>();
while(list.size()>0) {
for(int i=Math.min(n-1,list.size()-1);i>=0;i--) {
outList.add(list.get(i));
list.remove(i);
}
}
Reversing the complete list, n is same as length of list:
It can be added to list(like a queue) and then retrieved from the rear side(like a stack). So it doesnt require an index.
LinkedList<Integer> list = new LinkedList<>();
for (int i = 1; i < 9; i++) {
list.addLast(i);
}
int n = 2;
System.out.println(list);
LinkedList<Integer> outList = new LinkedList<>();
while(list.size()>0) {
outList.addLast(list.removeLast());//last element retrieved first
}
System.out.println(outList);

Related

Is there a way to iterate through a 2d list where it'll access the elements in order by first index, second, etc

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);

Unintended modification in Java

I have the following Java code:
List<List<Integer>> list1 = new ArrayList<List<Integer>>(rankings);
for (int i = k + 1; i < rankings.size(); i++) {
for (int j = 0; j < rankings.get(0).size(); j++) {
int index = rankings.get(i).indexOf(j);
list1.get(i).set(index, map.get(j));
}
}
// ...
int newrank = sort(list1.get(i), 0, list1.get(i).size() - 1); // sorts list1
list1 came out sorted, but rankings came out sorted as well. How can I prevent this?
All I wanted to do is to create a duplicate of rankings so that the original copy won't be affected while I sort the temporary, copied array.
Thanks in advance.
new ArrayList<>(list) copies the reference here, not cloning the objects, every amends made in one element will affect both lists.
You can add the elements manually to clone it:
for (List<Integer> intList: rankings) {
List<Integer> someIntCopy = new ArrayList<>();
someIntCopy.addAll(intList);
list1.add(someIntCopy);
}

How to find the Missing Elements in a given sequence array list using java?`

1.I have an Integer array list with a starting element and arraylist limit.
Example [5,6,9,10]
2.In which I have to iterate and find the missing element and its position.
According to the above example ,my output should be number 7 (position3 ),number 8 (position 4) are missing.
3.Now I am getting all the numbers printed instead of getting the missing elements.
Below is the code :
public static List<Integer> issue_ret=new ArrayList<>();
Iterator<Integer> iter = issue_ret.iterator();
while(iter.hasNext()){
int value = iter.next();
if("1".equals(value)){
iter.remove();
}
else{
System.out.println("Missing value:"+value);
}
}
Can anyone help me to resolve this?
Suggest you a more efficient way than ArrayList.contains() but more limited:
ArrayList<Integer> list = new ArrayList<>(Arrays.asList(new Integer[]{5, 6, 9, 10}));
int head = list.get(0);
int tail = list.get(list.size() - 1);
int length = tail - head + 1;
int[] array = new int[length];
for (int i : list) {
array[i - head] = 1;
}
for (int i = 0; i < array.length; i++) {
if (array[i] == 0) {
System.out.println(String.format("Missing %d, position %d", i + head, i + 1));
}
}
The limit is: The top Integer number should not be too large. Anyway, it is a space for time way, whether to use depends on your actual needs.
You are comparing every element with 1
if("1".equals(value))
instead you should keep a counter which will start from your lists first element and then incremented by 1 and perform comparison with this counter.
Try,
List<Integer> integerList = new LinkedList<Integer>();
integerList.add(5);
integerList.add(6);
integerList.add(9);
integerList.add(10);
int first = integerList.get(0);
int last = integerList.get(integerList.size()-1);
for(int i=first+1; i<last; i++){
if(!integerList.contains(i))
System.out.println("Number Not in List : "+i);
}
By getting the first and last element from array you can know the start and end of the array and by iteration over that limit you can get what numbers are missing like below:
List<Integer> input = new ArrayList<Integer>();
input.add(5);
input.add(8);
int firstElement = input.get(0);
int lastElement = input.get(input.size()-1);
for(int i=firstElement+1, j=2; i<lastElement-1; i++,j++){
if(!input.contains(i))
System.out.println("Missing Number : "+i + "(position " + j+")");
}
As we already know that first element and last element is already present in last, no need to check that so we would be only checking of elements exist between first and last element.

split the elements in the array list

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));
}

How to merge two arraylists into one in ascending order

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.

Categories