2

adding an element to a linked list is known to be O(1).

However, adding it in position X is O(X) and if i want to add R elements in this position the total running time would be O(R*X).

but there must be an O(X+R) solution.

And the question is how to do the O(R+X) in java?

Ahmad Ibrahem
  • 97
  • 1
  • 6

3 Answers3

2

You have a list of pairs (element, X) where X is an index and element is the item you want to put under that index. Sort this list by X and add elements one after another using an Iterator. Here is an example:

Your input is: [(E1, 5), (E2, 3), (E3, 7)].

  1. Sort it by index: [(E2, 3), (E1, 5), (E3, 7)]

  2. Create an iterator and advance it by 3.

  3. Add E2 using an iterator.

  4. Advance the same iterator by 2 (5 - 3).

  5. Add E1.

  6. ...

Notice that this algorithm has an of-by-one bug. It should be relatively easy to fix it.

UPDATE: just noticed that your problem is much simpler. In your case just create an iterator, advance it X times and add elements one by one using that iterator.

Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
  • that is a slightly different problem – Lie Ryan Jul 22 '12 at 14:38
  • @Lie True enough, but it's a generalization of the asked problem, so.. that's fine in my book. The obvious simplifications can be left as an exercise for the reader I'd hope. – Voo Jul 22 '12 at 14:39
  • as far as what i know (The behavior of an iterator is unspecified if the underlying collection is modified) actually this solution is the first one that comes to mind .. but it seems it wont work in java – Ahmad Ibrahem Jul 22 '12 at 14:44
  • @AhmadIbrahem: interesting, can you point to some documentation/JavaDoc? I guess `LinkedList` is sufficient for OP. – Tomasz Nurkiewicz Jul 22 '12 at 14:48
  • The behaviour of an iterator is unspecified if the collection is modified _other than via the iterator itself_ - the suggestion was to use [ListIterator.add](http://docs.oracle.com/javase/6/docs/api/java/util/ListIterator.html#add(E)) – Ian Roberts Jul 22 '12 at 14:51
  • aha sorry i was looking at the Iterator documentation not the ListIterator thanks. – Ahmad Ibrahem Jul 22 '12 at 14:55
2

Assuming you're using java.util.LinkedList, there is the LinkedList.listIterator() method that returns a ListIterator:

public ListIterator listIterator(int index)

Returns a list-iterator of the elements in this list (in proper sequence), starting at the specified position in the list. [...]

The list-iterator is fail-fast: if the list is structurally modified at any time after the Iterator is created, in any way except through the list-iterator's own remove or add methods, the list-iterator will throw a ConcurrentModificationException. [...]

And you can use ListIterator.add() to safely add an item in the middle of the LinkedList:

void add(E e)

Inserts the specified element into the list (optional operation). [...]

For example, say you want to put list2 in the 5th position of the list1, you can do so by doing the following:

LinkedList list1 = ...;
LinkedList list2 = ...;

ListIterator it1 = list1.listIterator(5);
for (Object item : list2) {
    it1.add(item);
}
Lie Ryan
  • 62,238
  • 13
  • 100
  • 144
1

Put elements to collection and then you can use addAll method to add them all.

Mikko Maunu
  • 41,366
  • 10
  • 132
  • 135
  • i actually like this answer :) – Ahmad Ibrahem Jul 22 '12 at 15:01
  • I like it too, but according reasonable looking comment (removed) this solution is clearly not correct. I removed answer for a moment and tried to find out what is the main difference of using ListIterator.add directly and using it via addAll method. I couldn't find it - so I undeleted this answer and maybe somebody tells and I will get enlightened. – Mikko Maunu Jul 22 '12 at 15:10