简体   繁体   中英

What is the time complexity of getting the headSet of a TreeSet in Java? Also, what if I call the headSet method 'n' times?

I was doing a hackerrank question that requires me to find out the number of shifts that need to occur to sort an array using Insertion Sort without actually sorting the array with insertion sort because otherwise that would be O(n^2) time-complexity. Here is my code that gets timed out, From what I know. calling the headSet method n times should come to around O(n logn).

static class MyComp implements Comparator<Integer>{
    @Override
    public int compare(Integer o1, Integer o2) {
        return o1 <= o2 ? -1: 1;
    }
}



// Complete the insertionSort function below.
static int insertionSort(int[] arr) {

    SortedSet<Integer> set = new TreeSet<>(new MyComp());
    int count=0;
    for(int i=arr.length-1; i>=0;i--){
        set.add(arr[i]);
        int pos = set.headSet(arr[i]).size();
       // System.out.println(pos);
        if(pos>0){
            count=count+pos;
        }

    }

    return count;
}

The complexity of creating a headset is O(1)

Why?

Because a headset is not a new set. It is actually a view of an existing set. Creating one doesn't involve copying the original set, and doesn't even involve finding the "bound" element in the set.

Thus, doing it N times is O(N) .

However, the reason that your code is not O(N) is that

  set.headSet(someElement).size();

is NOT O(1) . The reason is that the size() method on a subset view of a TreeSet is computed by counting the elements in the view.

(AFAIK, this is not stated in the javadocs, but you can deduce it from looking at the source code for TreeSet and TreeMap .)

Stephen C isn't even close and I have no idea how it has positive upvotes or is the accepted answer. Treeset access is O(log(n)) obviously, not O(1). So first off, there's no way on earth this could possibly be O(n), it's at best O(n*log(n)).

But is it? No. It's even worse. Headset is NOT A VIEW of an existing set like Stephen says, it's a new set. This is obviously the case because you can modify the headset by adding an element to it. You can't modify a view, and if that referred to the original set, it'd be a massive pain.

You can test it with the following code:

        TreeSet<Integer> test=new TreeSet<>();
        long time=System.currentTimeMillis();
        Random r=new Random(5);
        for (int i=0; i<1e6; i++)
            test.add(i);
        long ans=0;
        for (int i=0; i<1e6; i++) {
            int l=r.nextInt((int)1e6);
            ans+=test.headSet(l).size();
        }
        System.out.println(ans+" "+(System.currentTimeMillis()-time));

If it were O(n), it would run in 1/100th of a second. If it were O(log(n)), it would run in about 2 seconds. You can see this takes about 10^4 seconds. Your code is O(n^2).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM