Recipe 5.10. Selecting the nth Smallest Element of a Sequence
2011-07-19 00:14
218 查看
Solution
Perhaps you can do better, if the sequence is big, has been shuffled enough, and comparisons between its items are costly. Sort is very fast, but in the end (when applied to a thoroughly shuffled sequence of length n) it always takes O(n log n) time, while there exist algorithms that can be used to get the nth smallest element in time O(n). Here is a function with a solid implementation of such an algorithm:
import random
def select(data, n):
" Find the nth rank ordered element (the least value has rank 0). "
# make a new list, deal with <0 indices, check for valid index
data = list(data)
if n<0:
n += len(data)
if not 0 <= n < len(data):
raise ValueError, "can't get rank %d out of %d" % (n, len(data))
# main loop, quicksort-like but with no need for recursion
while True:
pivot = random.choice(data)
pcount = 0
under, over = [ ], [ ]
uappend, oappend = under.append, over.append
for elem in data:
if elem < pivot:
uappend(elem)
elif elem > pivot:
oappend(elem)
else:
pcount += 1
numunder = len(under)
if n < numunder:
data = under
elif n < numunder + pcount:
return pivot
else:
data = over
n -= numunder + pcount
Perhaps you can do better, if the sequence is big, has been shuffled enough, and comparisons between its items are costly. Sort is very fast, but in the end (when applied to a thoroughly shuffled sequence of length n) it always takes O(n log n) time, while there exist algorithms that can be used to get the nth smallest element in time O(n). Here is a function with a solid implementation of such an algorithm:
import random
def select(data, n):
" Find the nth rank ordered element (the least value has rank 0). "
# make a new list, deal with <0 indices, check for valid index
data = list(data)
if n<0:
n += len(data)
if not 0 <= n < len(data):
raise ValueError, "can't get rank %d out of %d" % (n, len(data))
# main loop, quicksort-like but with no need for recursion
while True:
pivot = random.choice(data)
pcount = 0
under, over = [ ], [ ]
uappend, oappend = under.append, over.append
for elem in data:
if elem < pivot:
uappend(elem)
elif elem > pivot:
oappend(elem)
else:
pcount += 1
numunder = len(under)
if n < numunder:
data = under
elif n < numunder + pcount:
return pivot
else:
data = over
n -= numunder + pcount
相关文章推荐
- Find the nth to last element of a singly linked list
- [LeetCode] Find the k-th Smallest Element in the Union of Two Sorted Arrays
- give two sorted array, find the k-th smallest element of union of A and B
- Search the Nth element of Level M in a binary tree
- Find the smallest window of a certain sequence
- Find the k-th Smallest Element in the Union of Two Sorted Arrays
- [CrackCode] 2.2 Find the nth to last element of a singly linked list
- struts-config.xml配置文件顺序异常: The content of element type "struts-config" must match
- web.xml The content of element type "web-app" must match "
- [Silverlight]Element is already the child of another element与Cannot resolve TargetProperty解决方案
- 减治法——搜索第k小元素(Decrease and Conquer by a Factor - Finding the kth smallest element)
- Study Android, Step by Step(三) The sequence of reading Android Document
- cvc-elt.1: Cannot find the declaration of element 'beans'.
- The content of element type "resultMap" must match "(constructor?,id*,result*,association*,collecti
- The content of element type "package" must match "(result-types?,interceptors?...
- The content of element type "session-factory" must match "(property*,mapping*,(class-cache| collect
- 数组空间Given a sequence of numbers (or array).Find the maximum distance between all the same numbers.
- The content of element type "session-factory" must match "(property*,mapping*,(class-cache|collectio
- The content of element type "struts-config" must match "(display-name?,description?,data-sources?,fo
- CareerCup Find the smallest range that includes at least one number from each of the k sorted lists.