二分搜尋應用: 找第k小的配對距離_Find K-th Smallest Pair Dist_Leetcode #719

更新於 發佈於 閱讀時間約 5 分鐘

題目敘述 719. Find K-th Smallest Pair Distance


給定一個輸入陣列nums和 參數k。

請找出第k小的pair distance是多少?


pair distance定義為 abs( nums[i] - nums[j]), i 不等於j

也就是任意兩陣列元素之間的差值絕對值


測試範例

Example 1:

Input: nums = [1,3,1], k = 1
Output: 0
Explanation: Here are all the pairs:
(1,3) -> 2
(1,1) -> 0
(3,1) -> 2
Then the 1st smallest distance pair is (1,1), and its distance is 0.

第一小的pair distance 是 0

Example 2:

Input: nums = [1,1,1], k = 2
Output: 0

第一小的pair distance 是 0
第二小的pair distance 是 0

Example 3:

Input: nums = [1,6,1], k = 3
Output: 5

第一小的pair distance 是 0
第二小的pair distance 是 5
第三小的pair distance 是 5

約束條件

Constraints:

  • n == nums.length

n = 陣列長度。

  • 2 <= n <= 10^4

陣列長度n介於2~一萬之間。

  • 0 <= nums[i] <= 10^6

每個陣列元素都介於0~一百萬之間。

  • 1 <= k <= n * (n - 1) / 2

參數k介於1 ~ C(n,2) 之間


觀察

除了暴力法計算全部pair dist再排序之外,其實還有更好的方法。


假如nums排序之後,那就變成從小到大依序放好的序列

這時候可以用最小pair dist和最大pair dist作為上下區間

往中間夾擠,看到哪一回合的時候,當下的pair dist剛好是第k小的。


演算法 排序前處理 + 二分搜尋法


承接觀察點的思考,先做前處理,將nums排序

這樣就滿足binary search的前提,接著用最小pair dist和最大pair dist作為上下區間

不斷砍半往中間夾擠pair dist,看到哪一回合的時候,當下的pair dist剛好是第k小的



程式碼 排序前處理 + 二分搜尋法

class Solution(object):
def countPairs(self, array, dist):
count = 0

# 累積看當下的 pair dist是第幾小的pair dist
for i in range(len(array)):
count += bisect.bisect_right(array, array[i] + dist, lo = i) - i - 1
return count

def smallestDistancePair(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
nums.sort()
low, high = min([abs(nums[i] - nums[i+1]) for i in range(len(nums) - 1)]), abs(nums[0] - nums[-1])

while low < high:
mid = (low + high)//2


if self.countPairs(nums, mid) < k:
# 假如不是第k小,而且還太小,則下一輪 pair dist猜大一點
low = mid + 1
elif self.countPairs(nums, mid) >= k:
# 假如不是第k小,而且還太大,則下一輪 pair dist猜小一點
# 假如mid是第k小,則下一輪 pair dist猜小一點,確認沒有更小的值也滿足
high = mid

return low


複雜度分析

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

前處理排序耗時O( n log n )

後續while loop + countPairs 總耗時也是O( n log n)


時間複雜度: O( n )

臨時變數用到長度為O(n)的list,所需空間為O(n)


關鍵知識點


遇到已排序的序列做搜尋,聯想到二分搜尋法。

如果輸入是亂序的,可以先做前處理排序,滿足二分搜尋法的前提。


強烈建議讀者一起復習相關的二分搜尋法框架和範例,鞏固知識點!

合縱連橫: 二分搜尋法框架_理解背後的本質


Reference

[1] 719. Find K-th Smallest Pair Distance

留言
avatar-img
留言分享你的想法!
小松鼠-avatar-img
發文者
2024/08/14
林燃(創作小說家)
avatar-img
小松鼠的演算法樂園
95會員
427內容數
由有業界實戰經驗的演算法工程師, 手把手教你建立解題的框架, 一步步寫出高效、清晰易懂的解題答案。 著重在讓讀者啟發思考、理解演算法,熟悉常見的演算法模板。 深入淺出地介紹題目背後所使用的演算法意義,融會貫通演算法與資料結構的應用。 在幾個經典的題目融入一道題目的多種解法,或者同一招解不同的題目,擴展廣度,並加深印象。
2024/05/27
給定一個輸入非負整樹陣列nums,請找出k值,使得陣列中恰好有k個元素大於等於 k。如果無解,回傳-1。尋找k值的方法包括排序法和二分搜尋法,時間複雜度都為O(n log n),空間複雜度為O(1)。關鍵知識點是當解空間具有遞增或遞減的性質時,可以用二分搜尋法加快搜尋效率。
Thumbnail
2024/05/27
給定一個輸入非負整樹陣列nums,請找出k值,使得陣列中恰好有k個元素大於等於 k。如果無解,回傳-1。尋找k值的方法包括排序法和二分搜尋法,時間複雜度都為O(n log n),空間複雜度為O(1)。關鍵知識點是當解空間具有遞增或遞減的性質時,可以用二分搜尋法加快搜尋效率。
Thumbnail
2024/03/19
這篇文章,會帶著大家複習以前學過的二分搜尋法(Binary Search)框架, 並且以二分搜尋法的概念為核心, 貫穿一些相關聯的題目,透過框架複現來幫助讀者理解這個實用的演算法框架。 Binary search 二分搜尋法框架 用途: 在已經排序好的數列中尋找目標值。
Thumbnail
2024/03/19
這篇文章,會帶著大家複習以前學過的二分搜尋法(Binary Search)框架, 並且以二分搜尋法的概念為核心, 貫穿一些相關聯的題目,透過框架複現來幫助讀者理解這個實用的演算法框架。 Binary search 二分搜尋法框架 用途: 在已經排序好的數列中尋找目標值。
Thumbnail
2024/03/14
找出區間[1, n] 內的軸心點位置。通過介紹直覺法、改良直覺法和二分搜尋等算法,最終給出了解析解(推導軸心點的公式解),提供了對應的程式碼和參考資料。該問題的最優解是使用解析解,能夠在O(1)的時間複雜度內找到答案。
Thumbnail
2024/03/14
找出區間[1, n] 內的軸心點位置。通過介紹直覺法、改良直覺法和二分搜尋等算法,最終給出了解析解(推導軸心點的公式解),提供了對應的程式碼和參考資料。該問題的最優解是使用解析解,能夠在O(1)的時間複雜度內找到答案。
Thumbnail
看更多
你可能也想看
Thumbnail
「欸!這是在哪裡買的?求連結 🥺」 誰叫你太有品味,一發就讓大家跟著剁手手? 讓你回購再回購的生活好物,是時候該介紹出場了吧! 「開箱你的美好生活」現正召喚各路好物的開箱使者 🤩
Thumbnail
「欸!這是在哪裡買的?求連結 🥺」 誰叫你太有品味,一發就讓大家跟著剁手手? 讓你回購再回購的生活好物,是時候該介紹出場了吧! 「開箱你的美好生活」現正召喚各路好物的開箱使者 🤩
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
題目敘述 Longest Arithmetic Subsequence of Given Difference 給定一個整數陣列nums,請找出給定公差difference的最長的等差數列的長度是多少?
Thumbnail
題目敘述 Longest Arithmetic Subsequence of Given Difference 給定一個整數陣列nums,請找出給定公差difference的最長的等差數列的長度是多少?
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
輸入給定一個已經從小到大排序好,而且彼此互質的整數陣列, 請問任取兩數分別當作分子、分母,第k小的分數是多少? 輸出請以 [分子,分母] 的形式回傳答案。
Thumbnail
輸入給定一個已經從小到大排序好,而且彼此互質的整數陣列, 請問任取兩數分別當作分子、分母,第k小的分數是多少? 輸出請以 [分子,分母] 的形式回傳答案。
Thumbnail
題目敘述 題目會給定我們一個二維陣列,要求我們計算內部元素相同的column row pairs總共有多少條? 註: pair的定義就是row i 和 column j 彼此內部元素值都相同,這樣就算一條pair。 題目的原文敘述 測試範例 Example 1: Input: gr
Thumbnail
題目敘述 題目會給定我們一個二維陣列,要求我們計算內部元素相同的column row pairs總共有多少條? 註: pair的定義就是row i 和 column j 彼此內部元素值都相同,這樣就算一條pair。 題目的原文敘述 測試範例 Example 1: Input: gr
Thumbnail
題目敘述 題目會給定我們兩個整數陣列作為輸入nums1, nums2,要求我們找出兩個陣列的差異值。 找出在nums1但是不在nums2的元素,以陣列的形式放在answer[0]輸出。 找出在nums2但是不在nums1的元素,以陣列的形式放在answer[1]輸出。 題目的原文敘述
Thumbnail
題目敘述 題目會給定我們兩個整數陣列作為輸入nums1, nums2,要求我們找出兩個陣列的差異值。 找出在nums1但是不在nums2的元素,以陣列的形式放在answer[0]輸出。 找出在nums2但是不在nums1的元素,以陣列的形式放在answer[1]輸出。 題目的原文敘述
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News