1. 程式人生 > >leetcode - 最小移動次數使陣列元素相等

leetcode - 最小移動次數使陣列元素相等

思路 (假設陣列每次都已被排好序)

  • 每次使得小於等於最大值的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

總結

只要能找到規律, 優化就不是事