Reputation: 369
Is it possible? If not, given an array of size n, how do I know if its better to just sort the array?
Upvotes: 9
Views: 24338
Reputation: 18906
in this complete answer (with C++ code) i found here - What is the best way to get the minimum or maximum value from an Array of numbers - com - it clearly show that the total number of comparisons is 3n/2 - 2 if n is even (and for odd the constant is 3/2 ) .
so after ignoring 2 constants ( qualifier of 3/2, and -2 ) which have no effect for enough large n , it obviously belongs to O(n) and it is linear in terms of complexity but in terms of efficiency (if i can say so) it is 1.5n and is very excellent
Upvotes: 0
Reputation: 881463
With just the unsorted array, there is no way to do this in sub-linear time. Since you don't know which element is the largest and smallest, you have to look at them all, hence linear time.
The best sort you'll find will be worse than that, probably relative to n log n
so it will be "better" to do the linear scan.
There are other ways to speed up the process if you're allowed to store more information. You can store the minimum and maximum using the following rules:
By doing it that way, probably the vast majority of retrieving min/max are constant time. It's only when you've removed a value which was the min or max does the next retrieval require linear time for one retrieval.
The next retrieval after that will again be constant time since you've calculated and stored them, assuming you don't remove the min/max value in the interim again.
Pseudo-code for just the maximum could be as simple as:
def initList ():
list = []
maxval = 0
maxcount = 0
In that initialisation code above, we simply create the list and a maximum value and count. It would be easy to also add the minimum value and count as well.
To add to the list, we follow the rules above:
def addToList (val):
list.add (val) error on failure
# Detect adding to empty list.
if list.size = 1:
maxval = val
maxcount = 1
return
# If no maximum known at this point, calc later.
if maxcount = 0:
return
# Adding less than current max, ignore.
if val < maxval:
return
# Adding another of current max, bump up count.
if val = maxval:
maxcount += 1
return
# Otherwise, new max, set value and count.
maxval = val
maxcount = 1
Deleting is quite simple. Just delete the value. If it was the maximum value, decrement the count of those maximum values. Note that this only makes sense if you know the current maximum - if not, you were already in the state where you were going to have to calculate it so just stay in that state.
The count becoming zero will indicate the maximum is now unknown (you've deleted them all):
def delFromList (val):
list.del (val) error on failure
# Decrement count if max is known and the value is max.
# The count will become 0 when all maxes deleted.
if maxcount > 0 and val = maxval:
maxcount -= 1
Getting the maximum is then a matter of knowing when it needs to be calculated (when maxcount
is zero). If it doesn't need to be calculated, just return it:
def getMax ():
# raise exception if list empty.
error if list.size = 0
# If maximum unknown, calculate it on demand.
if maxcount = 0:
maxval = list[0]
for each val in list:
if val = maxval:
maxcount += 1
elsif val > maxval:
maxval = val
maxcount = 1
# Now it is known, just return it.
return maxval
All that pseudo-code uses seemingly global variables, list
, maxval
and maxcount
. In a properly engineered system, they would of course be instance variables so that you can run multiple lists side-by-side.
Upvotes: 9
Reputation: 399
For unsorted array min/max complexity is O(N). No way to outperform it. For sorted arrays 0(1) but sort is 0{N log N). and if you need to search for min/max only ones or near it sort is not useful. But if you go this operation many times look at some of search structures such as Rb-tree or heap to reorganize date for avoid linear time in search.
Upvotes: 2
Reputation: 104060
Given the generic question:
Can I find the max/min value in an unsorted Array in sub linear time?
I can't imagine any mechanism that would make this happen.
However, if you keep a reference to the min and max value and update the values on every insert / append / replace operation, the amortized cost of min / max lookups can be very cheap.
Sorting the array is very expensive compared to a simple linear scan to find the min and max, so only sort if there is some other benefit. (Of course, insertion sort can provide very similar properties to updating the min and max values on every insert / append / replace operation, so it might be acceptable enough.)
Upvotes: 5