TopK大問題的另一種解法

2021-10-01 08:43:02 字數 1605 閱讀 1234

不久前介紹了堆排序python堆排序之heapq,主要是解決下面這個題目

在未排序的陣列中找到第 k 個最大的元素。請注意,你需要找的是陣列排序後的第 k 個最大的元素,而不是第 k 個不同的元素。

示例 1:

輸入: [3,2,1,5,6,4] 和 k = 2

輸出: 5

示例 2:

輸入: [3,2,3,1,2,4,5,5,6] 和 k = 4

輸出: 4

說明:

你可以假設 k 總是有效的,且 1 ≤ k ≤ 陣列的長度。

這是很經典的題目,有很多解法,除了上面說到的最小堆:heapq之外,今天覆習的時候,又發現大佬的另一種解法,可以說是想法獨特了。專門來記錄下。

下面是原始碼:

這種方法就是把原列表分為兩部分,以k作為索引分割為a、b兩個列表,然後遍歷b列表,把裡面每個元素拿來和a列表中的最小值比較,最終目的是保證a列表是原列表中資料最大的部分。

這個想法在別的解題方法中還真沒見過,很多人用的是「偷懶」的方法,面試中肯定用不了。還有些用的是排序來做的,**量就比較大了。

前方高能

class solution:

def findkthlargest(self, nums, k):

""":type nums: list[int]

:type k: int

:rtype: int

"""# nums.sort()

# return nums[-k]        

import random

def partition(nums, left, right):

p = random.randint(left, right)

nums[p], nums[right] = nums[right], nums[p]

i = left - 1

for j in range(left, right):

if nums[j] <= nums[right]:

i += 1

nums[i], nums[j] = nums[j], nums[i]

nums[i+1], nums[right] = nums[right], nums[i+1]

# print(nums[p])

return i+1

def select(nums, left, right, k):

if left == right:

return nums[left]

p = partition(nums, left, right)

pos = p - left + 1            

if k == pos:

return nums[p]

elif k < pos:

return select(nums, left, p-1, k)

else:

return select(nums, p+1, right, k-pos)

return select(nums, 0, len(nums)-1, len(nums)-k+1)

回文數的另一種解法

題目描述 判斷乙個整數是否是回文數。回文數是指正序 從左向右 和倒序 從右向左 讀都是一樣的整數。示例 1 輸入 121 輸出 true 示例 2 輸入 121 輸出 false 解釋 從左向右讀,為 121 從右向左讀,為 121 因此它不是乙個回文數。示例 3 輸入 10 輸出 false 解釋...

另一種階乘問題

大家都知道階乘這個概念,舉個簡單的例子 5!1 2 3 4 5.現在我們引入一種新的階乘概念,將原來的每個數相乘變為i不大於n的所有奇數相乘例如 5 1 3 5.現在明白現在這種階乘的意思了吧!現在你的任務是求出1 2 n 的正確值 n 20 輸入 第一行輸入乙個a a 20 代表共有a組測試資料 ...

另一種階乘問題

描述 大家都知道階乘這個概念,舉個簡單的例子 5!1 2 3 4 5.現在我們引入一種新的階乘概念,將原來的每個數相乘變為i不大於n的所有奇數相乘例如 5 1 3 5.現在明白現在這種階乘的意思了吧!現在你的任務是求出1 2 n 的正確值 n 20 輸入 第一行輸入乙個a a 20 代表共有a組測試...