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

总结

只要能找到规律, 优化就不是事儿

posted @ 2019-09-21 15:08  但是我拒绝  阅读(314)  评论(1编辑  收藏  举报