題目連結:
題目意譯:
你被給定一整數陣列 nums 以及一整數 k。你可以將 nums 分拆成一個或多個子序列使得 nums 中每個元素恰好出現在其中一個子序列中。
回傳最少所需之子序列數量,使得每個子序列中最大值與最小值之差值至多為 k。
一個子序列為一個可以由另一個序列藉由刪除若干個或是不刪除任何元素,且不更動剩餘元素的相對順序而得來的序列。
限制:
1 ≦ nums.length ≦ 10 ^ 5
0 ≦ nums[i] ≦ 10 ^ 5
0 ≦ k ≦ 10 ^ 5
範例測資:
範例 1:
輸入: nums = [3,6,1,2,5], k = 2
輸出: 2
解釋:
我們可以將 nums 分拆成兩個子序列 [3,1,2] 和 [6,5]。
在第一個子序列中的最大值與最小值之差值為 3 - 1 = 2。
在第二個子序列中的最大值與最小值之差值為 6 - 5 = 1。
由於創造了兩個子序列,我們回傳 2??梢宰C明 2 為最少所需的子序列之數量。
範例 2:
輸入: nums = [1,2,3], k = 1
輸出: 2
解釋:
我們可以將 nums 分拆成兩個子序列 [1,2] 和 [3]。
在第一個子序列中的最大值與最小值之差值為 2 - 1 = 1。
在第二個子序列中的最大值與最小值之差值為 3 - 3 = 0。
由於創造了兩個子序列,我們回傳 2。注意到另一個最佳解是將 nums 分拆成兩個子序列 [1] 和 [2,3]。
範例 3:
輸入: nums = [2,2,4,5], k = 0
輸出: 3
解釋:
我們可以將 nums 分拆成兩個子序列 [2,2] 、 [4] 和 [5]。
在第一個子序列中的最大值與最小值之差值為 2 - 2 = 0。
在第二個子序列中的最大值與最小值之差值為 4 - 4 = 0。
在第三個子序列中的最大值與最小值之差值為 5 - 5 = 0。
由於創造了三個子序列,我們回傳 3??梢宰C明 3 為最少所需的子序列之數量。
解題思維:
因為我們要找的是子序列,並且我們實際上只需要在乎一個子序列中的最小值與最大值,因此我們可以直接排序 nums(小到大或大到小都可以,以下用小到大為例)。
接著取排序後的第 0 個元素 nums[0] 作為第一個「子序列」(儘管已經不符合原本的定義,因為 nums 已經排序。但實際上這邊找到的子序列直接上可以對應回原始序列,所以不影響答案)的最小值,然後就一直把接下來的元素放到第一個子序列中直到遇到大過 nums[0] + k 之值(設其為 nums[i]);接著令 nums[i] 作為第二個子序列,然後重複與第一個子序列類似的動作直到有下一個元素大過 nums[i] + k;接著就繼續重複新增子序列並重複步驟直到 nums 掃完為止。
而可以看到我們不可能在為第一個子序列挑進更多個元素了,因為所有位於 nums[0] ~ nums[0] + k 的元素都在裡面了。而其他子序列也是同理。因此這樣子的挑法將會創造出最少量的子序列。
所以最後回傳過程中創造出的子序列之數量即為所求。
此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。