面试考题:海量数据(>2亿)中寻找第K小数和第K大数

思路:

用常规排序算法(选择,快速,冒泡,归并)解决这个问题,如果存储足够大的化,可以尝试去解决,然而否也。具体解决方案如下:

可以使用优先队列来解决,优先队列的大小为K,优先队列是基于堆实现的,如果寻找第K小数,可以使用大根堆,如果寻找第K大数可以使用小根堆。顺序遍历海量数据依次存入优先队列,当队列中的元素为大于K时候,进行出队,重复以上步骤,直到所有数据都遍历结束,最终返回最终优先队列中第一个元素即为我们所求解。

# coding:utf-8

class PriorityQueue(object):
	"""docstring for PriorityQueue"""
	def __init__(self,priority):
		super(PriorityQueue, self).__init__()
		self.queue = []
        # small:小根堆,big:大根堆
		self.priority = priority

	def put(self,val):
		self.queue.append(val)
		cur = self.qsize - 1
		while cur != 0:
			parent = (cur - 1) // 2
			if self.priority == "small":
				if self.queue[parent] <= self.queue[cur]:
					break
			else:
				if self.queue[parent] >= self.queue[cur]:
					break
			self.queue[parent],self.queue[cur] = self.queue[cur],self.queue[parent]
			cur = parent

	def get(self):
		if self.qsize == 0:
			raise Exception("The queue is empty!")
		val = self.queue[0]
		self.queue[0] = self.queue[-1]
		self.queue.pop()
		if self.qsize != 0:
			cur = 0
			while cur < self.qsize:
				left = cur * 2 + 1
				right = cur * 2 + 2
				if left >= self.qsize or right >= self.qsize:
					break
				if self.priority == "small":
					if self.queue[cur] <= min(self.queue[left],self.queue[right]):
						break
					if self.queue[left] < sself.queue[right]:
						self.queue[cur],self.queue[left] = self.queue[left],self.queue[cur]
						cur = left
					else:
						self.queue[cur],self.queue[right] = self.queue[right],self.queue[cur]
						cur = right
				else:
					if self.queue[cur] >= max(self.queue[left],self.queue[right]):
						break
					if self.queue[left] < self.queue[right]:
						self.queue[cur],self.queue[right] = self.queue[right],self.queue[cur]
						cur = right
					else:
						self.queue[cur],self.queue[left] = self.queue[left],self.queue[cur]
						cur = left
		return val

	@property
	def qsize(self):
		return len(self.queue)
		

def findMaxK(nums,k):
	# 使用优先队列寻找K大数
	pq = PriorityQueue("small")
	for num in nums:
		pq.put(num)
		if pq.qsize > k:
			pq.get()

	return pq.get()

def findMinK(nums,k):
	# 使用优先队列寻找K小数
	pq = PriorityQueue("big")
	for num in nums:
		pq.put(num)
		if pq.qsize > k:
			pq.get()

	return pq.get()
nums = [4,5,6,1,2,0,-2,56,87,100,45]
print(findMinK(nums,3))
print(findMaxK(nums,1))

好了,写完了,如果对您有用,点个赞呗!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值