2021-08-19:超级洗衣机。假设有 n 台超级洗衣机放在同一排上。开始的时候,每台洗衣机内可能有一定量的衣服,也可能是空的。在每一步操作中,你可以选择任意 m (1 ≤ m ≤ n) 台洗衣机,与此同时将每台洗衣机的一件衣服送到相邻的一台洗衣机。给定一个非负整数数组代表从左至右每台洗衣机中的衣物数量,请给出能让所有洗衣机中剩下的衣物的数量相等的最少的操作步数。如果不能使每台洗衣机中衣物的数量相等,则返回 -1。

福大大 答案2021-08-19:

这道题是见过就会,没见过就不会。
首先看能否平均分配。如果不能平均分配,就不进行下一步了;如果能平均分配,就下一步。
情况一,+a、i、-b,a正和b正取最大值。
情况二,+a、i、+b,a正和b正取最大值。
情况三,-a、i、-b,a正+b正。
情况四,-a、i、+b,a正和b正取最大值。
遍历数组,取最大值就是需要的返回值。
代码里第2种方法,数组的每个元素减去了平均值,方便计算。
时间复杂度:O(N)。
额外空间复杂度:O(1)。

代码用golang编写。代码如下:

package main

import "fmt"

func main() {
    arr := []int{1, 2, 3, 4, 5}
    ret := findMinMoves1(arr)
    fmt.Println(ret)
    ret = findMinMoves2(arr)
    fmt.Println(ret)
}

func findMinMoves1(arr []int) int {
    if len(arr) == 0 {
        return 0
    }
    size := len(arr)
    sum := 0
    for i := 0; i < size; i++ {
        sum += arr[i]
    }
    if sum%size != 0 {
        return -1
    }
    avg := sum / size
    leftSum := 0
    ans := 0
    for i := 0; i < len(arr); i++ {
        leftRest := leftSum - i*avg
        rightRest := (sum - leftSum - arr[i]) - (size-i-1)*avg
        if leftRest < 0 && rightRest < 0 {
            ans = getMax(ans, Abs(leftRest)+Abs(rightRest))
        } else {
            ans = getMax(ans, getMax(Abs(leftRest), Abs(rightRest)))
        }
        leftSum += arr[i]
    }
    return ans
}

func findMinMoves2(arr []int) int {
    if len(arr) == 0 {
        return 0
    }
    size := len(arr)
    sum := 0
    for i := 0; i < size; i++ {
        sum += arr[i]
    }
    if sum%size != 0 {
        return -1
    }
    avg := sum / size
    sum = 0
    //数组每个元素全部减去平均值
    for i := 0; i < size; i++ {
        arr[i] -= avg
        sum += arr[i]
    }
    leftSum := 0
    ans := 0
    for i := 0; i < len(arr); i++ {
        leftRest := leftSum
        rightRest := sum - leftSum - arr[i]
        if leftRest < 0 && rightRest < 0 {
            ans = getMax(ans, Abs(leftRest)+Abs(rightRest))
        } else {
            ans = getMax(ans, getMax(Abs(leftRest), Abs(rightRest)))
        }
        leftSum += arr[i]
    }
    //数组恢复
    for i := 0; i < size; i++ {
        arr[i] += avg
    }
    return ans
}

func Abs(a int) int {
    if a < 0 {
        return -a
    } else {
        return a
    }
}

func getMax(a int, b int) int {
    if a > b {
        return a
    } else {
        return b
    }
}

执行结果如下:
图片


左神java代码