滄海一粟 第k小的分數(最小堆+生成應用) Leetcode #786

小松鼠-avatar-img
發佈於演算法題目解析 個房間
更新於 發佈於 閱讀時間約 5 分鐘

題目敘述

輸入給定一個已經從小到大排序好,而且彼此互質的整數陣列
請問任取兩數分別當作分子、分母,第k小的分數是多少?

輸出請以[分子,分母]的形式回傳答案。


原本的英文題目敘述


測試範例

Example 1:

Input: arr = [1,2,3,5], k = 3
Output: [2,5]
Explanation: The fractions to be considered in sorted order are:
1/5, 1/3, 2/5, 1/2, 3/5, and 2/3.
The third fraction is 2/5.

Example 2:

I
nput: arr = [1,7], k = 1
Output: [1,7]

約束條件

Constraints:

  • 2 <= arr.length <= 1000

陣列長度介於2~1000之間。

  • 1 <= arr[i] <= 3 * 10^4

每個元素介於1~三萬之間。

  • arr[0] == 1

第一個元素保證是1

  • arr[i] is a prime number for i > 0.

第一個元素之外的都是質數。

  • All the numbers of arr are unique and sorted in strictly increasing order.

數字彼此都不同,而且嚴格遞增排序。

  • 1 <= k <= arr.length * (arr.length - 1) / 2

k 落在 C(n,2) 以內的數字。


演算法 最小堆 + 最佳化生成

比較小的分數一定是真分數,真分數就是分子比分母小

例如:

1/2, 1/3, 1/5, 2/3, 2/5 ...等等


因此可以過濾掉另一半假分數的情況。

例如:

2/1, 3/1, 5/1, 3/2, 5/2 ...等等


一開始先建立一個空的最小堆,接著初始化成1/a, a是所有題目供應互質的整數。

問第k小,所以就是pop次,每次pop的時候,動態生成下一個最接近的分數往上成長。

第k次pop拿到的,恰好就是第k小的分數


說明:
第一次pop拿到的會是第一小的分數,
第二次pop拿到的會是第二小的分數,
...
第k次pop拿到的的會是第k小的分數


這是來自於minHeap最小堆的特性,pop的元素具有由小到大遞增的性質


程式碼 最小堆 + 最佳化生成

class Solution:
def kthSmallestPrimeFraction(self, arr: List[int], k: int) -> List[int]:

minHeap = []

# Initialize to 1/a, where a is integer in input array
for i in range(len(arr)):
heapq.heappush(minHeap,(1/arr[i], 0, i) )

# Pop k times, then latest item is the k-th smallest fraction
for _ in range(k):
fraction, numerator, denominator = heapq.heappop( minHeap )

if numerator + 1 < denominator:
# Grow to next closet fraction
heapq.heappush(minHeap, ( (arr[numerator+1])/arr[denominator], numerator+1, denominator) )

# k-th smallest fraction
return [ arr[numerator], arr[denominator] ]

複雜度分析

時間複雜度: O(k log n)

k次pop,每次動態生成對應的adjustment需要log(n)的時間成本。


空間複雜度: O(n)

初始化之後,minHeap堆積大小為O(n)。

每次迭代最多一進一出,minHeap堆積大小空間成本為O(n)


關鍵知識點

找前k大的元素,可以用最大堆maxHeap來滿足

同樣道理

找前k小的元素,可以用最小堆minHeap來滿足

當k比較小的時候,堆積演算法會比sorting來的有效率,
因為sorting至少要花費O( n lo n)


Reference

[1] K-th Smallest Prime Fraction - LeetCode

留言
avatar-img
留言分享你的想法!
小松鼠-avatar-img
發文者
2024/09/03
🔼用Python來實現 Min Heap 最小堆提及了這篇文章,趕快過去看看吧!
avatar-img
小松鼠的演算法樂園
96會員
427內容數
由有業界實戰經驗的演算法工程師, 手把手教你建立解題的框架, 一步步寫出高效、清晰易懂的解題答案。 著重在讓讀者啟發思考、理解演算法,熟悉常見的演算法模板。 深入淺出地介紹題目背後所使用的演算法意義,融會貫通演算法與資料結構的應用。 在幾個經典的題目融入一道題目的多種解法,或者同一招解不同的題目,擴展廣度,並加深印象。
2024/05/29
Leetcode 精選75題 題目與題解 熱門考點 目錄 (持續更新中) 建議從左側目錄 或者 按Ctrl+F輸入關鍵字進行搜尋
Thumbnail
2024/05/29
Leetcode 精選75題 題目與題解 熱門考點 目錄 (持續更新中) 建議從左側目錄 或者 按Ctrl+F輸入關鍵字進行搜尋
Thumbnail
2024/04/15
這篇文章,會帶著大家複習以前學過的配對模型與Stack框架, 並且以括弧配對的應用題與概念為核心, 貫穿一些相關聯的題目,透過框架複現來幫助讀者理解這個演算法框架。 首先,Stack本身具有Last-In First-Out 後進先出的特質。 再根據題目所需要的資訊利用Stack去儲存索引
Thumbnail
2024/04/15
這篇文章,會帶著大家複習以前學過的配對模型與Stack框架, 並且以括弧配對的應用題與概念為核心, 貫穿一些相關聯的題目,透過框架複現來幫助讀者理解這個演算法框架。 首先,Stack本身具有Last-In First-Out 後進先出的特質。 再根據題目所需要的資訊利用Stack去儲存索引
Thumbnail
2024/02/29
題目敘述 題目會給我們一個字串s。 要求我們移除字串中的星號,還有刪除星號左手邊最靠近的第一個字元。 以字串的形式返回輸出答案。 題目的原文敘述 測試範例 Example 1: Input: s = "leet**cod*e" Output: "lecoe" Explanation:
Thumbnail
2024/02/29
題目敘述 題目會給我們一個字串s。 要求我們移除字串中的星號,還有刪除星號左手邊最靠近的第一個字元。 以字串的形式返回輸出答案。 題目的原文敘述 測試範例 Example 1: Input: s = "leet**cod*e" Output: "lecoe" Explanation:
Thumbnail
看更多
你可能也想看
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
全球科技產業的焦點,AKA 全村的希望 NVIDIA,於五月底正式發布了他們在今年 2025 第一季的財報 (輝達內部財務年度為 2026 Q1,實際日曆期間為今年二到四月),交出了打敗了市場預期的成績單。然而,在銷售持續高速成長的同時,川普政府加大對於中國的晶片管制......
Thumbnail
全球科技產業的焦點,AKA 全村的希望 NVIDIA,於五月底正式發布了他們在今年 2025 第一季的財報 (輝達內部財務年度為 2026 Q1,實際日曆期間為今年二到四月),交出了打敗了市場預期的成績單。然而,在銷售持續高速成長的同時,川普政府加大對於中國的晶片管制......
Thumbnail
題目敘述 Find K-th Smallest Pair Distance 給定一個輸入陣列nums和 參數k。 請找出第k小的pair distance是多少? pair distance定義為 abs( nums[i] - nums[j]), i 不等於j 也就是任意兩陣列元素差值的絕對值
Thumbnail
題目敘述 Find K-th Smallest Pair Distance 給定一個輸入陣列nums和 參數k。 請找出第k小的pair distance是多少? pair distance定義為 abs( nums[i] - nums[j]), i 不等於j 也就是任意兩陣列元素差值的絕對值
Thumbnail
給定一個輸入非負整樹陣列nums,請找出k值,使得陣列中恰好有k個元素大於等於 k。如果無解,回傳-1。尋找k值的方法包括排序法和二分搜尋法,時間複雜度都為O(n log n),空間複雜度為O(1)。關鍵知識點是當解空間具有遞增或遞減的性質時,可以用二分搜尋法加快搜尋效率。
Thumbnail
給定一個輸入非負整樹陣列nums,請找出k值,使得陣列中恰好有k個元素大於等於 k。如果無解,回傳-1。尋找k值的方法包括排序法和二分搜尋法,時間複雜度都為O(n log n),空間複雜度為O(1)。關鍵知識點是當解空間具有遞增或遞減的性質時,可以用二分搜尋法加快搜尋效率。
Thumbnail
題目給定一個布林代數的二元樹,要求我們計算最後的結果。 葉子節點都是真假值 非葉子節點都是布林運算子
Thumbnail
題目給定一個布林代數的二元樹,要求我們計算最後的結果。 葉子節點都是真假值 非葉子節點都是布林運算子
Thumbnail
題目敘述 輸入給定一個二元的二維矩陣grid 每次可以翻轉一條row,讓每個元素的01反相。 也可以翻轉一條column,讓每個元素的01反相。 可以操作任意多次。 最後把每條row視為一條二進位表達式的數字,並且進行加總,得到最後的分數。 請問分數的最大值是多少? 原本的英文題目敘
Thumbnail
題目敘述 輸入給定一個二元的二維矩陣grid 每次可以翻轉一條row,讓每個元素的01反相。 也可以翻轉一條column,讓每個元素的01反相。 可以操作任意多次。 最後把每條row視為一條二進位表達式的數字,並且進行加總,得到最後的分數。 請問分數的最大值是多少? 原本的英文題目敘
Thumbnail
輸入給定一個已經從小到大排序好,而且彼此互質的整數陣列, 請問任取兩數分別當作分子、分母,第k小的分數是多少? 輸出請以 [分子,分母] 的形式回傳答案。
Thumbnail
輸入給定一個已經從小到大排序好,而且彼此互質的整數陣列, 請問任取兩數分別當作分子、分母,第k小的分數是多少? 輸出請以 [分子,分母] 的形式回傳答案。
Thumbnail
題目會給定一個陣列nums和一個目標值goal。計算子陣列總和=goal的數目有多少。演算法包含前綴和和字典的技巧,時間複雜度為O(n),空間複雜度為O(n)。
Thumbnail
題目會給定一個陣列nums和一個目標值goal。計算子陣列總和=goal的數目有多少。演算法包含前綴和和字典的技巧,時間複雜度為O(n),空間複雜度為O(n)。
Thumbnail
題目敘述 題目會給兩個陣列nums1和nums2。 題目要求我們從中同步選擇長度為k的子序列,並且最大化子序列的分數, 回傳最高的分數值。 分數的定義: 分數 = (nums1[i0] + nums1[i1] +...+ nums1[ik - 1]) * min(nums2[i0] ,
Thumbnail
題目敘述 題目會給兩個陣列nums1和nums2。 題目要求我們從中同步選擇長度為k的子序列,並且最大化子序列的分數, 回傳最高的分數值。 分數的定義: 分數 = (nums1[i0] + nums1[i1] +...+ nums1[ik - 1]) * min(nums2[i0] ,
Thumbnail
題目敘述 題目會給定一個陣列nums 和 給定的k值,要求我們找出陣列裡第k大的元素。 題目的原文敘述 測試範例 Example 1: Input: nums = [3,2,1,5,6,4], k = 2 Output: 5 第二大的元素為5​ Example 2: Input:
Thumbnail
題目敘述 題目會給定一個陣列nums 和 給定的k值,要求我們找出陣列裡第k大的元素。 題目的原文敘述 測試範例 Example 1: Input: nums = [3,2,1,5,6,4], k = 2 Output: 5 第二大的元素為5​ Example 2: Input:
Thumbnail
題目敘述 題目會給我們一個輸入陣列nums,和一個指定的k值。 請問,在輸入陣列nums中,有幾個子陣列的元素總合恰好為k ? 例如: nums = [1,2,3], k = 3 則有兩個子陣列的元素總合為3,分別是[1,2] 和 [3] 如果是第一次聽到或接觸前綴和prefix的同學
Thumbnail
題目敘述 題目會給我們一個輸入陣列nums,和一個指定的k值。 請問,在輸入陣列nums中,有幾個子陣列的元素總合恰好為k ? 例如: nums = [1,2,3], k = 3 則有兩個子陣列的元素總合為3,分別是[1,2] 和 [3] 如果是第一次聽到或接觸前綴和prefix的同學
Thumbnail
題目會給定一個陣列,裡面有大有小,可以把數字的大小類比成高度 要求我們找出陣列裡面的相對極大值(relative max value)所在的陣列索引 也就是說當下這個元素,大於左邊鄰居的元素值,也大於右邊鄰居的元素值
Thumbnail
題目會給定一個陣列,裡面有大有小,可以把數字的大小類比成高度 要求我們找出陣列裡面的相對極大值(relative max value)所在的陣列索引 也就是說當下這個元素,大於左邊鄰居的元素值,也大於右邊鄰居的元素值
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News