ETH官方钱包

前往
大廳
主題

LeetCode - 330. Patching Array 解題心得

Not In My Back Yard | 2022-02-12 00:00:11 | 巴幣 0 | 人氣 365

題目連結:


題目意譯:
給定一個已排序整數陣列 nums 以及一整數 n,新增/添補一些元素到陣列中使得範圍 [1, n] 中的任意數字可以藉由陣列中某些元素加總而得到。

回傳最少所需添補之次數。

限制:
1 ≦ nums.length ≦ 1000
1 ≦ nums[i] ≦ 10 ^ 4
nums 以升序排序。
1 ≦ n ≦ 2 ^ 31 - 1



範例測資:
範例 1:
輸入: nums = [1,3], n = 6
輸出: 1
解釋:
nums 之組合為 [1] 、 [3] 、 [1,3],其形成可能的總和:1 、 3 、 4。
現在如果我們新增/添補數字 2 到 nums 中,組合變為 [1] 、 [2] 、 [3] 、 [1,3] 、 [2,3] 、 [1,2,3]。
可能之總和為 1 、 2 、 3 、 4 、 5 、 6,其覆蓋了範圍 [1, 6]。
所以我們只需要一次添補。

範例 2:
輸入: nums = [1,5,10], n = 20
輸出: 2
解釋: 兩次的添補可以為 [2, 4]。

範例 3:
輸入: nums = [1,2,2], n = 5
輸出: 0


解題思維:
假設我們已經知道現有的數字們可以保證組出範圍 [0, L - 1] 內的數字,其中 L ≧ 1。其中可以看到此時的 L 值為最小的、無法被加總組合得出的最小正整數。

因此我們掃過一次 nums,一開始我們能組成的數字範圍為 [0, 0],即 L = 1。當以下過程中有任何時刻 L > n 時,就代表著我們的任務完成了:
當 nums[i] ≦ L 時,則此時將會把可以表示的數字範圍 [0, L - 1] 擴張變為 [0, L + nums[i] - 1],因為此時不能表示的最小正整數為 L + nums[i];

而當 nums[i] > L 時,則代表著我們需要一次的添補。因為 nums 中的數字是非遞減地排序的,所以 nums[i] 之後不會有其他數字可以擴張範圍。而因為只要新增的數字 X 不超過 L 都可以使範圍擴張,因此要擴張就擴張的越大越好,因此我們應當新增一個數字 X = L。因此此時可表示之範圍變為 [0, 2L - 1],最小不能表示之正整數變為 2L。

結束之後,此時的 [0, L - 1] 將會含括 [0, n],因此過程中的添補次數由於每次都是盡量地擴張到最大,因此即為所求之最少次數。




此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。

創作回應

追蹤 創作集

作者相關創作

更多創作