頭角崢嶸 恰好k個元素大於等於k_Leetcode #1608 排序/二分搜尋 應用

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

題目敘述

給定一個輸入非負整樹陣列nums,請找出k值,使得陣列中恰好有k個元素 大於等於 k。

無果無解,回傳-1。


原文題目敘述


測試範例

Example 1:

Input: nums = [3,5]
Output: 2
Explanation: There are 2 values (3 and 5) that are greater than or equal to 2.

Example 2:

Input: nums = [0,0]
Output: -1
Explanation: No numbers fit the criteria for x.
If x = 0, there should be 0 numbers >= x, but there are 2.
If x = 1, there should be 1 number >= x, but there are 0.
If x = 2, there should be 2 numbers >= x, but there are 0.
x cannot be greater since there are only 2 numbers in nums.

Example 3:

Input: nums = [0,4,3,0,4]
Output: 3
Explanation: There are 3 values that are greater than or equal to 3.
輸入陣列裡,恰好有3個元素大於等於3

約束條件

Constraints:

  • 1 <= nums.length <= 100

輸入陣列長度介於1~100之間。

  • 0 <= nums[i] <= 1000

每個陣列元素值都介於0~1000之間。


觀察

恰好k個元素 >= k,找出k值。

k值最小可能是1,最大可能是n = len(nums),因為陣列裡最多也才n個元素。

演算法

怎麼找k值?

如果陣列由小到大排序好,那麼可以從左到右掃描每個元素,k值從n到1逐次遞減去檢查,假如有某一次疊代剛好發現有k個元素 >= k,那麼當下的k值就是答案;如果最後都不滿足,無解回傳-1。


如果陣列沒有排序好,那麼可以用二分搜尋法,從下邊界1和上邊界n去砍半夾擠k值,如果某回合剛好發現有k個元素素 >= k,那麼當下的k值就是答案;如果最後都不滿足,無解回傳-1。


程式碼 排序法

# Option_#1: Sorting

class Solution:
def specialArray(self, nums: List[int]) -> int:

# Keep nums sorted in ascending order
nums.sort()

n = len(nums)

if nums[0] >= n:
# First element is smaller than or equal to n
# There are exactly n elements larger than or equal to n
return n

for i in range(1, n):

# Number of elements on index from i to n-1
counting = n-i

if nums[i-1] < counting <= nums[i]:
# Exact element on i-th index is larger than or equal to counting
# There are exactly counting elements (from i-th index to n-1 th index) larger than or equal to counting
return counting

return -1

程式碼 二分搜尋法

# Option_#2: Binary search
class Solution:
def specialArray(self, nums: List[int]) -> int:

def check(k):
# Counting how many number >= k
return sum( 1 for number in nums if number >= k )
# ------------------------------------------

# Launch binary search to find k, such that there are exactly k number >= k in input array.
lower, upper = 1, len(nums)

while lower <= upper:

mid = lower + (upper - lower)//2

count_of_larger_equal = check(k=mid)
if count_of_larger_equal == mid:
return mid

elif count_of_larger_equal > mid:
# mid is too small
# try larger next round
lower = mid+1

else:
# mid is too large
# try smaller nexr round
upper = mid-1

return -1

複雜度分析

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

排序法排序耗費O(n log n),接著線性掃描耗費O(n),總時間成本依然為O(n log n)

二分搜尋法外層耗費O( log n),內層線性掃描耗費O(n),總時間成本為O( n log n)


空間複雜度: O(1)

兩種方法所用到的皆為固定尺寸的臨時變數,皆為常數級別O(1)。


關鍵知識點

如果解空間具有遞增或遞減的性質(近似於已排序),可以用二分搜尋法加快搜尋效率


Reference

[1] Special Array With X Elements Greater Than or Equal X - LeetCode

avatar-img
90會員
425內容數
由有業界實戰經驗的演算法工程師, 手把手教你建立解題的框架, 一步步寫出高效、清晰易懂的解題答案。 著重在讓讀者啟發思考、理解演算法,熟悉常見的演算法模板。 深入淺出地介紹題目背後所使用的演算法意義,融會貫通演算法與資料結構的應用。 在幾個經典的題目融入一道題目的多種解法,或者同一招解不同的題目,擴展廣度,並加深印象。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
這篇文章,會帶著大家複習以前學過的二分搜尋法(Binary Search)框架, 並且以二分搜尋法的概念為核心, 貫穿一些相關聯的題目,透過框架複現來幫助讀者理解這個實用的演算法框架。 Binary search 二分搜尋法框架 用途: 在已經排序好的數列中尋找目標值。
找出區間[1, n] 內的軸心點位置。通過介紹直覺法、改良直覺法和二分搜尋等算法,最終給出了解析解(推導軸心點的公式解),提供了對應的程式碼和參考資料。該問題的最優解是使用解析解,能夠在O(1)的時間複雜度內找到答案。
題目會給我們一個山形的輸入陣列,和目標值target,要求我們找出目標值所在的陣列索引。如果出現兩次,返回比較小的那一個,也就是比較靠左的那個索引值。 山形的意思就是說,從最左側到山頂最大值都是遞增,從山頂最大值到右側都是遞減。
題目給定一個已排序的輸入陣列,陣列裡面的數字自分別代表每篇論文的被引用數。 要求我們計算h-index。 h-index的定義: 找一個最大的h值,使得有h篇論文,個別論文的被引用數都 大於等於 h
題目會給定一個2D 二維的矩陣,矩陣內的元素值代表對應的高度,要求我們找出相對最高點,也就是(大樓)高度大於N4 東、南、西、北 四個鄰居的索引值。 題目保證矩陣內相鄰的元素值都不相同,也又是相鄰的兩兩相比較,一定有一個比較高,有一個比較矮。
題目會給定一個陣列,陣列裡面的元素分布就像一座山峰。 最大值的左邊都是上坡段,最大值的右邊都是下坡段。 要求我們找出陣列裡面的絕對極大值(absolute max value)所在的陣列索引
這篇文章,會帶著大家複習以前學過的二分搜尋法(Binary Search)框架, 並且以二分搜尋法的概念為核心, 貫穿一些相關聯的題目,透過框架複現來幫助讀者理解這個實用的演算法框架。 Binary search 二分搜尋法框架 用途: 在已經排序好的數列中尋找目標值。
找出區間[1, n] 內的軸心點位置。通過介紹直覺法、改良直覺法和二分搜尋等算法,最終給出了解析解(推導軸心點的公式解),提供了對應的程式碼和參考資料。該問題的最優解是使用解析解,能夠在O(1)的時間複雜度內找到答案。
題目會給我們一個山形的輸入陣列,和目標值target,要求我們找出目標值所在的陣列索引。如果出現兩次,返回比較小的那一個,也就是比較靠左的那個索引值。 山形的意思就是說,從最左側到山頂最大值都是遞增,從山頂最大值到右側都是遞減。
題目給定一個已排序的輸入陣列,陣列裡面的數字自分別代表每篇論文的被引用數。 要求我們計算h-index。 h-index的定義: 找一個最大的h值,使得有h篇論文,個別論文的被引用數都 大於等於 h
題目會給定一個2D 二維的矩陣,矩陣內的元素值代表對應的高度,要求我們找出相對最高點,也就是(大樓)高度大於N4 東、南、西、北 四個鄰居的索引值。 題目保證矩陣內相鄰的元素值都不相同,也又是相鄰的兩兩相比較,一定有一個比較高,有一個比較矮。
題目會給定一個陣列,陣列裡面的元素分布就像一座山峰。 最大值的左邊都是上坡段,最大值的右邊都是下坡段。 要求我們找出陣列裡面的絕對極大值(absolute max value)所在的陣列索引
你可能也想看
Google News 追蹤
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
這篇文章介紹了排列和組閤中的錯位排列和排容原理,並提供了一種相對樸實的解題方法。透過例子詳細解釋了選擇情況下的數學原理,讓讀者能夠理解並吸收。文章通過課堂上難以推敲的題目,提出了一個相對簡單的方式來解題。 圖片選自@pngtree
Thumbnail
分享在網路上看到的陣列題目。通常 for...of 的 value 是陣列中的每個值,那如果我們在迭代中對陣列操作會發生什麼事? 題目來源:https://x.com/_jayphelps/status/1774640511158022335?s=20
Thumbnail
高中數學主題練習—求等差數列某項與等差級數
Thumbnail
魔鬼藏在二分搜尋裡!輸出值代表的意含、題意產生的邊界條件,寫完模板才是挑戰的開始 Orz
Thumbnail
最近每天都有同學在解題社群提問這類型的問題,有些同學甚至po出解答來提問,表示看了解答卻還是看不懂,畢竟有時候「詳解」也沒辦法完整表達所有觀念。 排列組合是一門龐大的章節,許多人聞排組而色變,但排列組合的本質其實還是「窮舉法」,也就是把全部的可能通通列出來,只是很多地方我們可以透過計算讓窮舉變得更
描述順序的方式有很多種,可以用數字標示文字的方式,如下 文字 文字 文字 用數字標示文字的方式我覺得有個特質是,文字重要的程度是遞減的,也就是數字從一往後會越來越不重要。這個現象是我在寫這篇文的當下感覺到的,可能是我在過去經驗聽過有人說越重要的東西要先擺在前面;又或者是我在高中以前的
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
這篇文章介紹了排列和組閤中的錯位排列和排容原理,並提供了一種相對樸實的解題方法。透過例子詳細解釋了選擇情況下的數學原理,讓讀者能夠理解並吸收。文章通過課堂上難以推敲的題目,提出了一個相對簡單的方式來解題。 圖片選自@pngtree
Thumbnail
分享在網路上看到的陣列題目。通常 for...of 的 value 是陣列中的每個值,那如果我們在迭代中對陣列操作會發生什麼事? 題目來源:https://x.com/_jayphelps/status/1774640511158022335?s=20
Thumbnail
高中數學主題練習—求等差數列某項與等差級數
Thumbnail
魔鬼藏在二分搜尋裡!輸出值代表的意含、題意產生的邊界條件,寫完模板才是挑戰的開始 Orz
Thumbnail
最近每天都有同學在解題社群提問這類型的問題,有些同學甚至po出解答來提問,表示看了解答卻還是看不懂,畢竟有時候「詳解」也沒辦法完整表達所有觀念。 排列組合是一門龐大的章節,許多人聞排組而色變,但排列組合的本質其實還是「窮舉法」,也就是把全部的可能通通列出來,只是很多地方我們可以透過計算讓窮舉變得更
描述順序的方式有很多種,可以用數字標示文字的方式,如下 文字 文字 文字 用數字標示文字的方式我覺得有個特質是,文字重要的程度是遞減的,也就是數字從一往後會越來越不重要。這個現象是我在寫這篇文的當下感覺到的,可能是我在過去經驗聽過有人說越重要的東西要先擺在前面;又或者是我在高中以前的