LeetCode in Kotlin

3139. Minimum Cost to Equalize Array

Hard

You are given an integer array nums and two integers cost1 and cost2. You are allowed to perform either of the following operations any number of times:

Return the minimum cost required to make all elements in the array equal.

Since the answer may be very large, return it modulo 109 + 7.

Example 1:

Input: nums = [4,1], cost1 = 5, cost2 = 2

Output: 15

Explanation:

The following operations can be performed to make the values equal:

The total cost is 15.

Example 2:

Input: nums = [2,3,3,3,5], cost1 = 2, cost2 = 1

Output: 6

Explanation:

The following operations can be performed to make the values equal:

The total cost is 6.

Example 3:

Input: nums = [3,5,3], cost1 = 1, cost2 = 3

Output: 4

Explanation:

The following operations can be performed to make the values equal:

The total cost is 4.

Constraints:

Solution

import kotlin.math.max
import kotlin.math.min

class Solution {
    fun minCostToEqualizeArray(nums: IntArray, cost1: Int, cost2: Int): Int {
        var max = 0L
        var min = Long.MAX_VALUE
        var sum = 0L
        for (num in nums) {
            if (num > max) {
                max = num.toLong()
            }
            if (num < min) {
                min = num.toLong()
            }
            sum += num
        }
        val n = nums.size
        var total = max * n - sum
        // When operation one is always better:
        if ((cost1 shl 1) <= cost2 || n <= 2) {
            return (total * cost1 % LMOD).toInt()
        }
        // When operation two is moderately better:
        var op1 = max(0L, (((max - min) shl 1L.toInt()) - total))
        var op2 = total - op1
        var result = (op1 + (op2 and 1L)) * cost1 + (op2 shr 1L.toInt()) * cost2
        // When operation two is significantly better:
        total += op1 / (n - 2L) * n
        op1 %= n - 2L
        op2 = total - op1
        result = min(result, ((op1 + (op2 and 1L)) * cost1 + (op2 shr 1L.toInt()) * cost2))
        // When operation two is always better:
        for (i in 0..1) {
            total += n.toLong()
            result = min(result, ((total and 1L) * cost1 + (total shr 1L.toInt()) * cost2))
        }
        return (result % LMOD).toInt()
    }

    companion object {
        private const val MOD = 1000000007
        private const val LMOD = MOD.toLong()
    }
}