My first thought was a radix sort, but since that does depend on the value of the largest number, I'm don't think that it's strictly O(N) in this case.
Infarction
Posting Virtuoso
1,580 posts since May 2006
Reputation Points: 683
Solved Threads: 53
Yeah, that's what I was thinking too. Even counting sort depends on the range of values, so it wouldn't fit either. I'm out of ideas, sorry :(
Infarction
Posting Virtuoso
1,580 posts since May 2006
Reputation Points: 683
Solved Threads: 53
iamthwee
Posting Expert
5,950 posts since Aug 2005
Reputation Points: 1,543
Solved Threads: 439
>> You are given an array of length N, which contains values in the range from 0 to (N^2) - 1. You are to sort it in O(N) time.
2 questions to understand the question:
1. Why does the range of value matter? (size/range of value would have no impact on the order of algorithm from what I know)
2. When you say "in O(N) time" do you mean it's an algorithm of order N or you really mean some number of mili/micro/seconds.. ?
thekashyap
Practically a Posting Shark
811 posts since Feb 2007
Reputation Points: 254
Solved Threads: 75
1. It does affect algorithm runtime in several cases, especially when dealing with non-comparison based sorts (since it's proven that comparision based sorts cannot be guaranteed to run in better than O(n log n) time, they don't make the cut for this problem). Look at some of the sorts already mentioned in this thread.
2. Linear time with respect to the length of the input.
Infarction
Posting Virtuoso
1,580 posts since May 2006
Reputation Points: 683
Solved Threads: 53
Have you tried out SmoothSort ?
Its best case is O(n) and worst case is O(n log(n)) with the obvious downfall of difficult to implement.
~s.o.s~
Failure as a human
11,938 posts since Jun 2006
Reputation Points: 3,281
Solved Threads: 734
Since it does have the O(n log n) case, it wouldn't fit the requirements. And I've never seen an implementation of it outside of that paper... ;)
Infarction
Posting Virtuoso
1,580 posts since May 2006
Reputation Points: 683
Solved Threads: 53
But practically speaking, a sorting algo having O(n) as its worst case would be hard to get by. I guess the only choice the OP is left with is to pick a nice O(n log(n)) algo and make custom changes to it (depending on the problem statement) to bring it down to O(n) though achieving O(n) for worst case still looks kind of impossible.
And the reason Smoothsort is rarely used is because of the difficulty faced in its implementation.
~s.o.s~
Failure as a human
11,938 posts since Jun 2006
Reputation Points: 3,281
Solved Threads: 734
Well, in a normal case you'd be able to claim that radix sort, bucket sort, or counting sort (to name a couple) would run in O(n) time. But since they're all dependent on the range in some very small degree, seems like, the claim doesn't hold anymore.
Infarction
Posting Virtuoso
1,580 posts since May 2006
Reputation Points: 683
Solved Threads: 53
What about something like this:
Make buckets for the ranges 0..n-1, n..2n-1, ..., n^2-n..n^2-1.
Then, first go through the array and fill the buckets with counts of how many elements fall in the buckets (and maybe an array that you fill linearly alongside the count). Then _smartly_ (that's the key) base your strategy on the distribution of the elements in the buckets. (Of course, you'll need to figure out what strategy to use in linear time. But then again, since the counts associated with each bucket can be sorted in linear time using bucket sort.) By the way, you can allocate any amount of memory in constant time.
So maybe with the right smart selection of strategy, you can succeed in linear time.
Rashakil Fol
Super Senior Demiposter
2,658 posts since Jun 2005
Reputation Points: 1,135
Solved Threads: 177
Here's some ideas about strategy: First of all, consider an extreme case, where sqrt(n) buckets have sqrt(n) elements fall into them. Well, know (by induction) that any bucket with more than sqrt(n) elements and n possible values can be sorted in linear time using a recursive call to this same algorithm. The hard part is sorting those buckets in which the range of possible values has length N, but the number of values is much less than N (since this is closer to the general sorting problem).
Consider another extreme case. Suppose we get n/log(n) buckets of size log(n). Then each of these buckets can be sorted in log(n)(log(log(n)) time, which makes the total running time n*log(log(n)). That's obviously not the right algorithm to use, but it's much better than n*log(n).
Well, what _can_ we do? If we're to sort each of these buckets separately, we'll need to sort them in log(n) time (which is linear with respect to size).
And in general, if we consider the cases where we get n/f(n) buckets containing approximately f(n) elements each, then sorting these buckets naively will give overall n * log(f(n)) time. In "average" cases, we'll have a long tail of buckets with 2,1, and 0 elements, which means average case will take O(n) overall running time. But if f = log, then we get nlog(log(n)). And if f(n) = sqrt(n)/log(n), we get n*log(n) running time... But if f(n) = sqrt(n) or higher, then all of the sudden we get to call our algorithm recursively and get O(n) overall time. (And of course we're assuming we can get a way for our algorithm to be linear in the other cases.)
But then to solve the log(n) case, we'll need a way to sort (generally speaking) n elements in the range 1..e^n in O(n) time... And to solve the f(n) case, we'll need a way for 1..f^-1(n) in O(n) time. So ignore my previous post; this attack is going nowhere.
Rashakil Fol
Super Senior Demiposter
2,658 posts since Jun 2005
Reputation Points: 1,135
Solved Threads: 177
Are you sure you don't need to provide O(N) _average_ time?
Rashakil Fol
Super Senior Demiposter
2,658 posts since Jun 2005
Reputation Points: 1,135
Solved Threads: 177
hm... just an idea... what if you tried applying any of the otherwise O(n) algorithms, but took the sqrt of the data as you sorted it. That would cut out the polynomial range, leavning you from 0..N, which is then polynomial time. You'd have to make an extra run over the loop at the end to square everything back to it's actual value.
Infarction
Posting Virtuoso
1,580 posts since May 2006
Reputation Points: 683
Solved Threads: 53
Nope, won't do, unless he is ready to sacrifice the real values and accept the approximates. Think of it this way, would the data before squaring and after squaring be the same? I guess no. If you know the way floating point numbers are handled by the system, you would know what I am trying to convey.
~s.o.s~
Failure as a human
11,938 posts since Jun 2006
Reputation Points: 3,281
Solved Threads: 734