What is difference between a.remove(a.size()-1) and a.remove(a.indexOf(a.lastElement())) of Vectors Class in Java? Do they remove the same element?
a.remove(a.indexOf(a.lastElement())) gave me wrong output whereas a.remove(a.size()-1) is giving correct output.
Note: a is a Java Vector declared as
Vector<Integer> a = new Vector<Integer>();
a.remove(a.indexOf(a.lastElement())) is a very roundabout way of achieving roughly the same thing.
It gets the lasts element in the vector, tries to find the index of any element that is equal to it and then removes that element.
That is only roughly the same as a.remove(a.size()-1), because if the vector contains a second object that is equal to the last one (i.e. last.equals(otherElement) returns true), then that item will be removed instead.
a.remove(a.size()-1) is definitely the more correct (and faster) way to remove the last element.
Related
im working on a problem where i have to obtain all permutations of an arraylist of numbers. The only restriction is that any number cant start with 0, so if we have [0,1,2] we would obtain
[1,2,0]
[1,0,2]
[2,0,1]
[2,1,0]
i know how to do this with 3 loops but the thing is that i have to repeat this to different sets of numbers with differentes sizes, so i need one method that i can apply to different sets of numbers but i have no clue on how to do this. I imagine i have to used some kind of recursive function but i dont know how to implement it so the numbers cant start with a 0. Any ideas? please dont just post the code i want to understand the problem, thank you in advantage!!
Curious question! Interesting code kata.
I naively think I would have a recursive method that takes:
a list of the items currently chosen by the caller
a set of the items available for the callee
The method would iterate over the set to chose 1 more item and call itself with the list extended by this item, and the set reduced by this item. Upon return, remove from list, add back to set and go on with next item (take a defensive copy of the set of course).
If the current list is empty, the selected first item cannot be 0, as per your rules. If you must collect the permutations somewhere (not just print), a 3rd argument would be required for a collection or an observer.
The recursion obvioulsy stops when the available set is empty, at which point the permutation is sent to the collection or observer.
If items can repeat, you may have benefit from sorting them first in order to skip electing the same item again at a given position.
Beware this quires a recursion depth of N, for N items. But the danger is minimal because even with N=10000, it may not stackoverflow, but the CPU time to complete would be order(N!) (probably end of universe...)
You could solve this recursively as described here: Permutation of an ArrayList of numbers using recursion.
The only thing that is missing there is your restriction with the zeros, which could be solved somehow like this (the loop is taken from the example above):
for (List<Integer> al : myLists) {
// The part you need to add:
if (al.get(0) == 0) {
continue;
}
String appender = "";
for (Integer i : al) {
System.out.print(appender + i);
appender = " ";
}
System.out.println();
}
You basically check the first element of each permutation and skip the ones with a leading zero. The continue jumps to the next iteration of the loop and therefore to the next permutation.
What is the best performance method in Java (7,8) to eliminate integer elements of one Arraylist from another. All the elements are unique in the first and second lists.
At the moment I know the API method removeall and use it this way:
tempList.removeAll(tempList2);
The problem appears when I operate with arraylists have more than 10000 elements. For example when I remove 65000 elements, the delay appears to be about 2 seconds. But I need to opperate with even more large lists with more than 1000000 elements.
What is the strategy for this issue?
Maybe something with new Stream API should solve it?
tl;dr:
Keep it simple. Use
list.removeAll(new HashSet<T>(listOfElementsToRemove));
instead.
As Eran already mentioned in his answer: The low performance stems from the fact that the pseudocode of a generic removeAll implementation is
public boolean removeAll(Collection<?> c) {
for (each element e of this) {
if (c.contains(e)) {
this.remove(e);
}
}
}
So the contains call that is done on the list of elements to remove will cause the O(n*k) performance (where n is the number of elements to remove, and k is the number of elements in the list that the method is called on).
Naively, one could imagine that the this.remove(e) call on a List might also have O(k), and this implementation would also have quadratic complexity. But this is not the case: You mentioned that the lists are specifically ArrayList instances. And the ArrayList#removeAll method is implemented to delegate to a method called batchRemove that directly operates on the underlying array, and does not remove the elements individually.
So all you have to do is to make sure that the lookup in the collection that contains the elements to remove is fast - preferably O(1). This can be achieved by putting these elements into a Set. In the end, it can just be written as
list.removeAll(new HashSet<T>(listOfElementsToRemove));
Side notes:
The answer by Eran has IMHO two major drawbacks: First of all, it requires sorting the lists, which is O(n*logn) - and it's simply not necessary. But more importantly (and obviously) : Sorting will likely change the order of the elements! What if this is simply not desired?
Remotely related: There are some other subtleties involved in the removeAll implementations. For example, HashSet removeAll method is surprisingly slow in some cases. Although this also boils down to the O(n*n) when the elements to be removed are stored in a list, the exact behavior may indeed be surprising in this particular case.
Well, since removeAll checks for each element of tempList whether it appears in tempList2, the running time is proportional to the size of the first list multiplied by the size of the second list, which means O(N^2) unless one of the two lists is very small and can be considered as "constant size".
If, on the other hand, you pre-sort the lists, and then iterate over both lists with a single iteration (similar to the merge step in merge sort), the sorting will take O(NlogN) and the iteration O(N), giving you a total running time of O(NlogN). Here N is the size of the larger of the two lists.
If you can replace the lists by a sorted structure (perhaps a TreeSet, since you said the elements are unique), you can implement removeAll in linear time, since you won't have to do any sorting.
I haven't tested it, but something like this can work (assuming both tempList and tempList2 are sorted) :
Iterator<Integer> iter1 = tempList.iterator();
Iterator<Integer> iter2 = tempList2.iterator();
Integer current = null;
Integer current2 = null;
boolean advance = true;
while (iter1.hasNext() && iter2.hasNext()) {
if (advance) {
current = iter1.next();
advance = false;
}
if (current2 == null || current > current2) {
current2 = iter2.next();
}
if (current <= current2) {
advance = true;
if (current == current2)
iter1.remove();
}
}
I suspect removing from an ArrayList, is a perfromance hit since the list may either be divided when an element in the middle is removed, or if the list must be compacted after an element is removed. It may be faster to do this:
Create 'Set' of the elements to be removed
Create a new result ArrayList that you need, call it R. You can give it enough size at construction.
Iterate thru the original list you need elements from it removed, if the element is found in the Set, don't add it to R, otherwise add it.
This should have O(N); if creating the Set and a lookup in it is assumed constant.
Can someone please explain In Java how do you find middle element of a linked list in single pass?
I have googled it, but cannot seem to find a simple explanation on how to code it.
LinkedList<String> list = new LinkedList<>();
list.add("foo");
list.add("bar");
list.add("baz");
String middle = list.get(list.size()/2);
System.out.println(middle); // bar
The call to assign middle will pass through half of the list during the get call.
As pointed out in the comments, the middle is the worst place to operate on a LinkedList. Consider using another variation, such as ArrayList.
I think this is a sort of trick question that you see on lists of possible interview questions.
One solution would be to have two pointers to step through the list, one taking steps of two and one taking steps of one.
When the pointer that is taking two steps at a time reaches the end of the list, the one taking only one step will be halfway through.
I doubt that this practice is really useful though..
good luck!
Since it's a LinkedList, you won't be able to find out its size until after the first (and only) pass. To find the middle element, you need to know two things; what index is at the middle, and what is the value of the element at that index. Finding the middle index is easy--just make one pass through the list, keeping a counter of how many nodes there are. As you do this, you'll need to keep track of each element in a separate data structure, perhaps an ArrayList, since you're only allowed one pass through the LinkedList. Once you're done, half the counter to find the middle index, and return the ArrayList element at that index.
The pseudo code looks like this:
int count
ArrayList elements
for each node in LinkedList:
count++
elements.append(node)
middleIndex = count/2
middleElement = elements.getIndex(middleIndex)
return middleElement
Of course, you'll need to take care of the case where there isn't a single middle element.
Problem
I'm writing a simple Java program in which I have a TreeSet which contains Comparable elements (it's a class that I've written myself). In a specific moment I need to take only the first k elements from it.
What I've done
Currently I've found two different solution for my problem:
Using a simple method written by me; It copies the first k elements from the initial TreeSet;
Use Google Guava greatestOf method.
For the second option you need to call the method in this way:
Ordering.natural().greatestOf(mySet, 80))
But I think that it's useless to use this kind of invocation because the elements are already sorted. Am I wrong?
Question
I want to ask here which is a correct and, at the same time, efficient method to obtain a Collection derived class which contains the first k elements of a TreeSet?
Additional information
Java version: >= 7
You could use Guava's Iterables#limit:
ImmutableList.copyOf(Iterables.limit(yourSet, 7))
http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/Iterables.html#limit(java.lang.Iterable, int)
I would suggest you to use a TreeSet<YourComparableClass> collection, it seems to be the solution you are looking for.
A TreeSet can return you an iterator, and you can simply iterates K times, by storing the objects the iterator returns you: the elements will be returned you in order.
Moreover a TreeSet keep your elements always sorted: at any time, when you add or remove elements, they are inserted and removed so that the structure remains ordered.
Here a possible example:
public static ArrayList<YourComparableClass> getFirstK(TreeSet<YourComparableClass> set, int k) {
Iterator<YourComparableClass> iterator = set.iterator();
ArrayList<YourComparableClass> result = new ArrayList<>(k); //to store first K items
for (int i=0;i<k;i++) result.add(iterator.next()); //iterator returns items in order
//you should also check iterator.hasNext(); if you are not sure to have always a K<set.size()
return result;
}
The descendingIterator() method of java.util.TreeSet yields elements from greatest to least, so you can just step it however many times, inserting the elements into a collection. The running time is O(log n + k) where k is the number of elements returned, which is surely fast enough.
If you're using a HashSet, on the other hand, then the elements in fact are not sorted, so you need to use the linear-time selection method that you indicated.
I'm a python programmer, but currently I'm reading through Java code to get some ideas. I have no programming experience at all with Java and I don't know how it's possible, but I couldn't get any information using Google about these functions.
if(pv.size() -2 < j)
pv.add(j+1, localpv.get(j));
else
pv.set(j+1, localpv.get(j));
This is the piece of code I need to decypher. pv and localpv are both vectors (I believe they are equivalent to lists in python?), and something is added to them. I can guess that one of them is adding them to a vector at a certain position (j+1), but then I have no idea what the other one does.
Can you please explain those two lines for me and maybe telling what are they equivalent to in python?
add inserts the specified element at the specified position
set replaces the element at the specified position
Checkout JavaDocs http://docs.oracle.com/javase/6/docs/api/java/util/Vector.html
add inserts an object at a position moving all other objects one back. set overwrites current object at that location.
You can look up the definitions of all Java methods in the API reference.
Vector.add(int index, E element)
Inserts the specified element at the specified position in this Vector.
Vector.set(int index, E element)
Replaces the element at the specified position in this Vector with the specified element.
The equivalent Python code would be
if len(pv) - 2 < j:
pv.insert(j+1, localpv[j])
else:
pv[j+1] = localpv[j]
The first one adds a new element on j+1'st position, the other one sets the value of existing j+1'st position with a given value.
I guess the author wanted to make sure he doesn't try to set a value of a non existing element of the list (vector).