leetcode - 最小移動次數使陣列元素相等
阿新 • • 發佈:2019-09-21
思路 (假設陣列每次都已被排好序)
- 每次使得小於等於最大值的n-1的數字加1,直接暴力求解會超時
- 改進一: 為了讓最小元素等於最大元素,至少需要陣列中最大值-最小值次, 所以以此為基礎再次暴力求解(參見下面第一個python程式碼)
- 改進二: 整個求解過程就是最小不斷去追最大, 直到兩者相等為止。\(max_{0}\)為原始陣列中的最大值, 更新後的\(max_{1}\)為原始陣列的第n-1個加上上一次的\((max-min)\),\(max_{2}\)為原始陣列的第n-2個加上上一次的\((max-min)\). . . 且可以發現每一次的min都是上一次的max,
- 最終的移動次數就是\(moves = \sum_{i=1}^{n-1}(a[i]-a[0])\) 其中n為陣列的長度
# 暴力求解 -> 超時 class Solution: def minMoves(self, nums) -> int: nums = sorted(nums) if len(nums) == 2: return nums[1]-nums[0] if len(nums) == 1 or len(nums) == 0: return 0 if nums[0] == nums[-2]: return nums[-1] - nums[0] # 達到目的必然會移動不少於max-min步, 因為最後的結果的max一定是大於原有max的, 所以min至少要先移動到原有max那裡去 count = nums[-1]-nums[0] for i in range(len(nums) - 1): nums[i] += count nums = sorted(nums) while nums[0] != nums[-1]: for i in range(len(nums)-1): nums[i] += 1 count += 1 nums = sorted(nums) return count
# 學習官方求解 修改後的 -> 通過
# 其實優化過程, 就是個找規律的過程
class Solution:
def minMoves(self, nums):
sums = sum(nums)
mins = min(nums)
mul = mins*len(nums)
return sums - mul
總結
只要能找到規律, 優化就不是事