Instead of using ArrayList for insertion, using LinkedList is more efficient. Here is the discussion of when to use LinkedList over ArrayList on StackOverFlow.

```
public class Solution {
class PairComp implements Comparator<int[]> {
public int compare(int[] p1, int[] p2){
int comp_h = Integer.compare(p2[0], p1[0]);
return comp_h == 0 ? Integer.compare(p1[1], p2[1]): comp_h;
}
}
public int[][] reconstructQueue(int[][] people) {
LinkedList<int[]> list = new LinkedList();
PriorityQueue<int[]> queue = new PriorityQueue<int[]>(1, new PairComp() );
for (int[] ppl: people){
queue.offer( ppl );
}
while ( ! queue.isEmpty() ) {
int[] pair = queue.poll();
list.add(pair[1], pair);
}
int[][] ret = new int[people.length][];
for (int i=0; i<list.size(); i++){
ret[i] = list.get(i);
}
return ret;
}
}
```

Shorter version without using PriorityQueue:

```
public class Solution {
public int[][] reconstructQueue(int[][] people) {
Arrays.sort(people,new Comparator<int[]>(){
public int compare(int[] p1, int[] p2){
return p1[0]!=p2[0]?Integer.compare(p2[0],p1[0]): Integer.compare(p1[1],p2[1]);
}
});
List<int[]> list = new LinkedList();
for (int[] ppl: people) list.add(ppl[1], ppl);
return list.toArray(new int[people.length][] );
}
}
```