tuna's blog

By tuna, history, 8 years ago, In English

Java: Arrays.sort(Integer) is more faster than Arrays.sort(int) in the worst case:

The main reason is that Java uses two different sorting algorithms in the cases you mentioned. In the Arrays.sort(int) (or other primitive types) case, Java uses Quicksort, which has a O(n^2) worst case. Instead, in the Arrays.sort(Object) case, it uses Mergesort, which has a O(n log n) worst case.

So some problems may give you Time Limit Exceeded when you use Arrays.sort(int) if there is an anti-quicksort test.

References:

http://codeforces.com/blog/entry/17565

http://stackoverflow.com/questions/3707190/why-java-arrays-use-two-different-sort-algorithms-for-different-types

Example 1:

Time limit exceeded because of Arrays.sort(int)

http://codeforces.com/contest/285/submission/20103799

Same code but Accepted because of Arrays.sort(Integer)

http://codeforces.com/contest/285/submission/20103803

Example 2:

Time limit exceeded on test 46 ( because of Arrays.sort(int) )

http://codeforces.com/contest/433/submission/20104326

Accepted after changing it to Arrays.sort(Integer)

http://codeforces.com/contest/433/submission/20104369

When does the worst case of Quicksort occur?

http://www.geeksforgeeks.org/when-does-the-worst-case-of-quicksort-occur/

But why is Quicksort more popular than Mergesort ?

1)Is in-place (MergeSort requires extra memory linear to number of elements to be sorted).

2)Has a small hidden constant.

Reference:

http://stackoverflow.com/questions/70402/why-is-quicksort-better-than-mergesort

  • Vote: I like it
  • +10
  • Vote: I do not like it

| Write comment?
»
8 years ago, # |
Rev. 4   Vote: I like it 0 Vote: I do not like it

I suggest O(n) optimization demonstrated below for time-constrained problems:

http://codeforces.com/contest/285/submission/20108766

Edit: my solution above is wrong as outputs mod n may colide (10^6 + 7 is not a prime).

»
8 years ago, # |
  Vote: I like it 0 Vote: I do not like it

You can add to the blog that one can easily sort primitive datatypes and not get TLE, just by shuffling the array randomly.

I've been a victim so I know :P

»
3 years ago, # |
  Vote: I like it +9 Vote: I do not like it

My solution got hacked due to this today. Should've used Integer array

  • »
    »
    3 years ago, # ^ |
      Vote: I like it +5 Vote: I do not like it

    you can still use quick sort while avoiding get hacked. The idea is to randomize the order of the input and then use quick sort. This should work as the probability of the worst case would be nearly non existent.

»
4 months ago, # |
  Vote: I like it 0 Vote: I do not like it

public class SortComparison {

static void quickSort(int[] a) {
    long start = System.currentTimeMillis();
    Arrays.sort(a);
    long end = System.currentTimeMillis();
    System.out.println("Arrays.sort() took time : " + (end - start)/1000.0);
}

static void mergeSortWithStreams(int[] a) {
    long start = System.currentTimeMillis();
    List<Integer> listInt = Arrays.stream(a).boxed().sorted().toList();
    long end = System.currentTimeMillis();
    System.out.println("Collections.sort() (mergeSortWithStreams) took time : " + (end - start)/1000.0);
}

static void mergeSortNormal(int[] a) {
    long start = System.currentTimeMillis();
    List<Integer> listInt = new ArrayList<>();
    for(int x : a) {
        listInt.add(x);
    }
    Collections.sort(listInt);
    long end = System.currentTimeMillis();
    System.out.println("Collections.sort() (mergeSortNormal) took time : " + (end - start)/1000.0);
}


public static void main(String[] args) {

    int[] a = new int[10000000];
    for(int i = 0; i < 10000000; i++) {
        a[i] = i;
    }
    int[] b = Arrays.stream(a).toArray();
    int[] c = Arrays.stream(a).toArray();

    //Arrays.sort() is dumb which uses quick sort (which is O(n^2) in worst case scenario)
    quickSort(a);

    //Collections.sort() uses merge sort
    mergeSortWithStreams(b);
    mergeSortNormal(c);
}

} Why I am getting below output now? Shouldn't it be other way round according to your blog. Arrays.sort() took time : 0.011 Collections.sort() (mergeSortWithStreams) took time : 0.248 Collections.sort() (mergeSortNormal) took time : 0.314

`