3

Is it true that ArrayDeque should be preferred over LinkedList in this scenario? Why is ArrayDeque better than LinkedList.

In my opinion, I should be using LinkedList instead of ArrayDeque, as there are quite a lot of poll and offer operation going on in this algorithm, and there is no random access to elements.

 public ArrayList<ArrayList<Integer>> levelOrder(TreeNode a) {
    Queue<TreeNode> q = new LinkedList<>();  // new ArrayDeque<>() ???
    q.offer(a);
    ArrayList<ArrayList<Integer>> ans = new ArrayList<ArrayList<Integer>>();
    while (q.peek() != null){ //returns null if empty
        ArrayList<Integer> list = new ArrayList<>();
        int n = q.size();
        for (int i = 0; i < n; i++){
            TreeNode node = q.poll();
            list.add(node.val);
            if (node.left != null) {
                q.offer(node.left);
            }
            if (node.right != null) {
                q.offer(node.right);
            }
        }
        ans.add(list);
    }
    return ans;
}
Saurav Sahu
  • 13,038
  • 6
  • 64
  • 79
  • 1
    The first answer in the link you added explaining very well why you should use `ArrayDeque`, and when you should use `LinkedList`. I nearly marked it a duplicate. – Yonlif Jun 26 '19 at 11:41
  • Possible duplicate of [When to use LinkedList over ArrayList in Java?](https://stackoverflow.com/questions/322715/when-to-use-linkedlist-over-arraylist-in-java) – Gpsy Jun 26 '19 at 13:35

1 Answers1

10

There are a number of tradeoffs to consider when deciding between ArrayDeque and LinkedList when treating the two as a doubly-ended queue.

Generally speaking, the LinkedList type has the following advantages:

  • The cost of adding an element is worst-case O(1), so no individual insertion will ever take too much time.
  • The cost removing an element from the ends is worst-case O(1), so no individual deletion will ever take too much time.

Generally speaking, the LinkedList type has the following major disadvantage:

  • Because elements in a LinkedList are not necessarily stored contiguously in memory, the LinkedList has poor locality of reference, and accesses may result in more cache misses, decreasing performance.

Generally speaking, the ArrayDeque type has the following advantages:

  • Because elements are stored contiguously, the ArrayDeque has great locality of reference, so element accesses will typically create few cache misses and thus lead to excellent performance.

Generally speaking, the ArrayDeque has the following disadvantage:

  • Although any sequence of n operations on an ArrayDeque will take time O(n), when the array capacity is exceeded on an insertion, the ArrayDeque may have to do O(n) work to copy elements. As a result, the worst-case performance of an ArrayDeque per operation is slower than a LinkedList.
  • Similarly, if the array capacity drops too low on a deletion, it may take time O(n) to resize the array, though, as before, any series of n operations on an ArrayDeque will take time O(n).

In your particular use case, since all you care about is the end-to-end efficiency of the level-order traversal, not the cost of any individual addition or removal of elements from the queue, it will probably be faster to use an ArrayDeque than a LinkedList. In a sense, the LinkedList type is generally only better if you need to have good worst-case performance on each operation performed, and that isn't the case here. The ArrayDeque is generally more performant when all you care about is end-to-end runtime.

Hope this helps!

Saurav Sahu
  • 13,038
  • 6
  • 64
  • 79
templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065