運輸問題
注珂珂喜歡吃香蕉。這裡有 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 種不同的船。每一艘船有乙個稀有值,任意兩艘船的稀有...