題目連結:
題目意譯:
給定一個已排序整數陣列 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],因此過程中的添補次數由於每次都是盡量地擴張到最大,因此即為所求之最少次數。
此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。