leetcode 2448. Minimum Cost to Make Array Equal(使数组相等的最小成本)

leetcode 2448. Minimum Cost to Make Array Equal(使数组相等的最小成本)_第1张图片

数组nums的元素每次可进行下面的操作:
每个元素+1 或者 -1。
操作一次的cost是cost[i].
问把nums的元素全部变为相等的元素需要的最小的cost.

思路:

nums的元素全部变为相等的元素,这个相等的元素是多少,现在不知道。
一旦知道了目标元素是多少,就可以直接计算cost.

所以需要求解的其实是这个相等的目标元素是多少。
它的可能性是 1 ~ 106 (nums[i]的范围),要在这个范围内找到一个数字,使cost最小。
那么需要用到binary search.

存在一个数字,nums所有元素在+1,-1的操作下变为这个数字的cost最小,
假设数字是a, 那么cost(a-1) > cost(a), cost(a+1) > cost(a),
在binary search中,如果cost(mid-1) > cost(mid), cost(mid+1) > cost(mid),
那么mid就是要找的目标数字。

如果cost(mid) > cost(mid-1), 说明要向左边去找,right=mid-1, 反之left = mid+1.

class Solution {
    public long minCost(int[] nums, int[] cost) {
        int left = 1;
        int right = 1000000;

        long res = Long.MAX_VALUE;

        //binary search
        while(left <= right) {
            int mid = left + (right-left)/2;
            long curCost = findCost(nums, cost, mid);
            res = Math.min(res, curCost);
            long rCost = findCost(nums, cost, mid+1);
            long lCost = findCost(nums, cost, mid-1);

            if(curCost < lCost && curCost < rCost) return res;
            else if(curCost > rCost) left = mid+1;
            else right = mid-1;
        }
        return res;
    }

    long findCost(int[] nums, int[] cost, int value){
        long res = 0;
        for(int i = 0; i < nums.length; i++) {
            long diff = Math.abs(nums[i] - value);
            res += diff * cost[i];
        }
        return res;
    }
}

或者直接先找目标数字,再求cost.
这个方法更快一些。
但是很神奇的是如果把mid=(left+right+1)/2换成mid=left+(right-left)/2就会TLE。

class Solution {
    public long minCost(int[] nums, int[] cost) {
        int left = 1;
        int right = 1000000;

        while(left < right){
            //mid = left+(right-left)/2会TLE
            int mid = (left + right +1)/2;
            long curCost = findCost(nums, cost, mid);
            long lCost = findCost(nums, cost, mid-1);

            if(curCost >= lCost) right = mid - 1;
            else left = mid;
        }
        return findCost(nums, cost, left);
    }

    long findCost(int[] nums, int[] cost, int val)
    {
        long ans = 0; 
        for(int i = 0; i< nums.length; i++)
        {
           ans += (long)Math.abs(nums[i]-val) * cost[i];
        }
        return ans;
    }
}

你可能感兴趣的:(leetcode,leetcode,算法)