【線上程式設計産品介紹】
阿裡雲開發者社群線上程式設計:
免費刷題大神器,助你拿到好offer
周賽月賽不停歇,做題還能領獎品
大賽筆試全真題,常做常新有驚喜
點選連結開始産品體驗:
https://developer.aliyun.com/coding本文為大家介紹的是“132.最優分組”的解法探究。先來看一下題目内容:
等級:容易
知識點:尺取法
檢視題目:最優分組給出一個長度為 n 的數組和一個數字 k ,你需要在數組中選出一些數字,這些數字兩兩之間的內插補點不能超過k。你需要判斷最多能夠挑出的數字個數。(n在[1, 100000]之間,k和數組中的數字在[1,1000000000]之間)
輸入數組長度n;選出的兩數字最大內插補點k;和一個長度為n的數組。
輸出最多能夠選出的數字個數。
示例1
輸入:
5
[13,4,6,9,20]
輸出:
3
解題方法:排序後周遊
很多同學在思考這道題的過程中,碰到最大的難點就是,一個數字可能同時屬于多個分組,而這個分組的大小,可能是從2~n任何一個數字。這樣的組合方式,如果用暴力的方法,挨個周遊的話,是非常恐怖的。
比如,如果這道題提供了一個長100的數組用例,那麼選出一組數可能的組合方式,就有2^100 ≈ 1024^10 ≈ 10^30種。
是以我們發現,拖累解題過程最直接的點,在于題目給的資料結構不合理。對一個無序的,可能很長的數組,怎麼可能短時間内周遊所有的“取一組數”的可能性呢?
于是,我們可以考慮,如何優化這道題提供的資料。對數組,在不違反題目要求的情況下,最簡單的優化方式就是排序。排序的時間複雜度很低,好的排序算法的空間複雜度為常數級,對本題影響很小。是以不妨假設對于一組有序的數字,再去考慮這道題,會不會發現簡單了不少?
當面對一組數字時,他們中最大的值和最小的值的內插補點如果不超過k,那麼其中任何兩個數字的內插補點,都一定不超過k。而有序數組,恰恰可以幫我們快速找到任何一組數字中的最大的值和最小的值,我們可以用一對指針,用右指針指向的值,與左指針指向的值做差,進而一次性判斷左右指針之間的值組成的一組數,是否滿足上面的條件。
當右指針與左指針的內插補點超過k時,我們可以嘗試移動左指針,重新滿足上面的條件。
當右指針與左指針的內插補點不超過k時,我們可以嘗試移動右指針,尋找所求值的最大值。
試着應用上面的思想,最佳方案應該可以達到:最壞情況下兩個指針各周遊一次數組,就可以得到正确答案了。
時間複雜度:O(nlogn)
看完是不是有了新思路了呢,快來試一下吧:
檢視題目:132.最優分組。
上一篇: 筆試算法模拟題精解之“Bob的花束” 下一篇: 筆試算法模拟題精解之“超車”