二分查詢 實際場景

2021-10-03 23:46:35 字數 2140 閱讀 9387

運輸問題

注珂珂喜歡吃香蕉。這裡有 n 堆香蕉,第 i 堆中有 piles[i] 根香蕉。警衛已經離開了,將在 h 小時後回來。

珂珂喜歡慢慢吃,但仍然想在警衛回來前吃掉所有的香蕉。

返回她可以在 h 小時內吃掉所有香蕉的最小速度 k(k 為整數)。

示例 1:

輸入: piles =[3

,6,7

,11], h =

8輸出:

4示例 2:

輸入: piles =[30

,11,23

,4,20

], h =

5輸出:

30示例 3:

輸入: piles =[30

,11,23

,4,20

], h =

6輸出:23

1<= piles.length <=10^

4piles.length <= h <=10^

91<= piles[i]

<=10^

9

koko 每⼩時最多吃⼀堆⾹蕉,如果吃不下的話留到下⼀⼩時再吃;如果吃完了這⼀堆還有胃⼝,也只會等到下⼀⼩時才會吃下⼀堆。在這個條件下,讓我們確定 koko 吃⾹蕉的最⼩速度(根/⼩時)

求「 h ⼩時內吃完⾹蕉的最⼩速度」,我們不妨稱為speed ,請問 speed 最⼤可能為多少,最少可能為多少呢?

顯然最少為 1,最⼤為 max(piles) ,因為⼀⼩時最多只能吃⼀堆⾹蕉。那麼暴⼒解法就很簡單了,只要 從 1 開始窮舉到 max(piles) ,⼀旦發現發現某個值可以在 h ⼩時內吃完所有⾹蕉,這個值就是最⼩速度

int

mineatingspeed

(int

piles,

int h)

return max;

}

注意這個 for 迴圈,就是在連續的空間線性搜尋,這就是⼆分查詢可以發揮作⽤的標誌。由於我們要求的是最⼩速度,所以可以⽤⼀個搜尋左側邊界的⼆分查詢來代替線性搜尋,提公升效率:

借助⼆分查詢技巧,演算法的時間複雜度為 o(nlogn)

int

mineatingspeed

(int

piles,

int h)

else

}return left;

}

剩下的輔助函式也很簡單,可以⼀步步拆解實現:

// 時間複雜度 o(n)

要在 d 天內運輸完所有貨物,貨物不可分割,如何確定運輸的最⼩載重呢(下⽂稱為 cap )?

其實本質上和 koko 吃⾹蕉的問題⼀樣的,⾸先確定 cap 的最⼩值和最⼤值分別為 max(weights) 和 sum(weights) 。

我們要求最⼩載重,所以可以⽤搜尋左側邊界的⼆分查詢演算法優化線性搜尋:

// 尋找左側邊界的⼆分查詢

intshipwithindays

(int

weights,

int d)

else

}return left;

}// 如果載重為 cap,是否能在 d 天內運完貨物?

boolean canfinish

(int

w,int d,

int cap)

}return

false

;}

for

(int i =

0; i < n; i++)if

(isok

(i))

return ans;

二分查詢 三種場景

也稱 折半查詢 binary search 使用前提 線性表採用順序儲存結構,表中元素按關鍵字有序排列 二分查詢是一種基於比較目標值和陣列中間元素的教科書式演算法。實現 維護兩個指標left,right,指標之間是搜尋區間 時間複雜度 o logn 空間複雜度 o 1 public int sear...

迭代二分查詢二分查詢

在寫這篇文章之前,已經寫過了幾篇關於改迭代二分查詢主題的文章,想要了解的朋友可以去翻一下之前的文章 bentley在他的著作 writing correct programs 中寫道,90 的計算機專家不能在2小時內寫出完整確正的二分搜尋演算法。難怪有人說,二分查詢道理單簡,甚至小學生都能明確。不過...

1128 二分 二分查詢

時間限制 10000ms 單點時限 1000ms 記憶體限制 256mb 描述nettle最近在玩 艦 因此nettle收集了很多很多的船 這裡我們假設nettle氪了很多金,開了無數個船位 去除掉重複的船之後,還剩下n 1 n 1,000,000 種不同的船。每一艘船有乙個稀有值,任意兩艘船的稀有...