面試題 一億個數中選取TopN python解決

2021-10-07 12:48:54 字數 2308 閱讀 8120

資料量過大,考慮記憶體和計算複雜度的問題,不能選取直接對10億個資料進行排序,再選取top100的數。

採用構建堆的方法,再對剩下的數在現成的堆中進行比對,替換,直到遍歷完所有數為止,找到top100的堆,步驟如下:

**如下:

class topn:

# 父節點下標

def parent(self, n):

return int((n - 1) / 2)

# 左節點下標

def left(self, n):

return 2 * n + 1

# 右節點下標

def right(self, n):

return 2 * n + 2

# 構建小頂堆,保證父節點小於左右子節點

def buildheap(self, n, data):

for i in range(1, n):

t = i

# 調整堆,如果節點比父親節點小,則交換

while t != 0 and data[t] < data[self.parent(t)]:

temp = data[t]

data[t] = data[self.parent(t)]

data[self.parent(t)] = temp

t = self.parent(t)

print(data)

# 調整data[i]

def adjust(self, i, n, data):

# 小於堆的根節點,不調整

if data[i] <= data[0]:

return

# 置換堆頂

temp = data[i]

data[i] = data[0]

data[0] = temp

# 調整堆頂

t = 0

while (self.left(t) < n and data[self.left(t)] < data[t]) or (self.right(t) < n and data[self.right(t)] < data[t]):

if self.right(t) < n and data[self.right(t)] < data[self.left(t)]:

# 右孩子更小,置換右孩子

temp = data[t]

data[t] = data[self.right(t)]

data[self.right(t)] = temp

t = self.right(t)

else:

# 否則置換左孩子

temp = data[t]

data[t] = data[self.left(t)]

data[self.left(t)] = temp

t = self.left(t)

# 尋找topn,調整data,將topn排到最前面

def findtopn(self, n, data):

# 先構建n個數的小頂堆

self.buildheap(n, data);

# n往後的數進行調整

for i in range(n, len(data)):

self.adjust(i, n, data)

return data

# 第一組測試 12個

arr1 = [58, 26, 45, 18, 22, 39, 96, 75, 80, 65, 63, 28]

print("原陣列:" + str(arr1))

topn = topn()

result = topn.findtopn(5, arr1)

print("陣列進行top-n調整:" + str(result))

# 第二組測試 隨機100個

"""import random

templist =

for i in range(100):

temp = random.randint(0, 1000)

print("原陣列:" + str(templist))

topn = topn()

result = topn.findtopn(5, templist)

print("陣列進行top-n調整:" + str(result))

"""

測試例項如下:

面試題40 最小k個數

題目 輸入n個整數,找出其中最小的k個數 思路 1 如果輸入的陣列可以改變,則基於第k個數來調整,是第k個數左邊的數都小於第k個數,右邊的數都大於第k個數 時間複雜度o n 思路1 void printkminnumberbymethod1 int arr,int length,int k int ...

面試題之最小K個數

最小 最大k個數 是面試容易提及的其中乙個問題,此處用快排思路解決。思路 因為當選取的樞紐元等於k時,樞紐元左邊的序列元素必定小於k,右邊的序列元素必定大於k。儘管序列內部是無序的,但此時結果已符合題意。為避免產生多餘的排序工作,我們只需要在遞迴的時候分歧選擇最接近k的方向即可,一旦等於k就停止遞迴...

面試題 17 14 最小K個數

leetcode 面試題 17.14.最小k個數 easy 題 但是這道題是想考什麼 明顯很多種解法 排序暴力 topk 問題 大頂堆 使用 bfprt 在o n 內求解前k小的數 最壞時間複雜度 o n o n o n 劍指 offer 40.最小的k個數 中的解法一 基於快排的思想 一次快排 二...