題目連結:
題目意譯:
你被給定一個索引值從 0 開始且包含著 n 個整數的陣列 nums。
每一秒,你將會對該陣列執行以下操作:
對於每一個位於範圍 [0, n - 1] 中的索引值 i,將 nums[i] 替換為 nums[i] 、 nums[(i - 1 + n) % n] 或是 nums[(i + 1) % n] 其中一者。
注意到所有元素是同時被替換的。
回傳讓陣列中所有元素相等最少所需要的秒數。
限制:
1 ≦ n == nums.length ≦ 10 ^ 5
1 ≦ nums[i] ≦ 10 ^ 9
範例測資:
範例 1:
輸入: nums = [1,2,1,2]
輸出: 1
解釋: 我們根據以下方式在 1 秒後使陣列元素全數相等:
- 在第 1 秒,將每一個索引值的數值替換成 [nums[3],nums[1],nums[3],nums[3]]。替換後,nums = [2,2,2,2]。
可以證明要讓陣列元素全數相等最少所需秒數為 1 秒。
範例 2:
輸入: nums = [2,1,3,3,2]
輸出: 2
解釋: 我們根據以下方式在 2 秒後使陣列元素全數相等:
- 在第 1 秒,將每一個索引值的數值替換成 [nums[0],nums[2],nums[2],nums[2],nums[3]]。替換後,nums = [2,3,3,3,3]。
- 在第 2 秒,將每一個索引值的數值替換成 [nums[1],nums[1],nums[2],nums[3],nums[4]]。替換後,nums = [3,3,3,3,3]。
可以證明要讓陣列元素全數相等最少所需秒數為 2 秒。
範例 3:
輸入: nums = [5,5,5,5]
輸出: 0
解釋: 由於一開始陣列中所有元素就已經相同了,因此不需要任何操作。
解題思維:
由於所有元素要相等勢必要從某個元素替換而來。
因此假設我們知道那個「某個元素」是什麼並令其值為 X,則要算出最短秒數很簡單——在 nums 中無視掉其餘的元素,只看「相鄰」的每一對 X。
假設現在有一對 X 的索引值分別是 i 和 j(i < j)。則要讓 i ~ j 中間的元素全部變成 X 的唯一方式就是從 i 和 j 向彼此「擴張」,因此我們會需要 floor((j - i) ÷ 2) 秒。
而總體所需的最少秒數即是每一對 X 之間所需的「擴張」秒數以及「第一個」X 往開頭「擴張」和「最後一個」X 往結尾「擴張」的最大者。
但實際上我們不知道 X 是啥。所以我們就試試看 nums 中每一種數字即可。當然,如果每一種數字都要掃過一次 nums 會太慢。
所以要嘛用雜湊表(Hash Table)來紀錄每一種數字「前一次」出現的索引值,這樣一來重新遇到同一種數字時便可以計算其中一對數字的所需「擴張」秒數;又或是直接把每一個數字與其索引值綁在一起,然後按照數字大小排序、數字一樣按索引值小到大排。這樣數字一樣就會擺在一起,所以掃過一次排序後的 nums 就可以掃過一次每一對數字對。
此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。