1818. 绝对差值和 | 刷题打卡

215 阅读2分钟

本文正在参与掘金团队号上线活动,点击 查看大厂春招职位

一、题目描述:

image.png

image.png

二、思路分析:

今天给大家分享的是力扣第235场周赛的第三题,当初比赛的时候AC了,没想到最后被rejude了。今天再重新做一遍看看吧。

错误的解法

比赛的时候我的想法是找出一个绝对值差值最大的位置,然后从nums1找到一个数字,替换这个位置上的nums1的数字。但是这其实是不对的,如下面这个case就无法通过。 [1,28,21] [9,21,20]

OK,我们再来重新看一下题目,题目有提到【最小化】,数据量10^5。所以我们可以往O(NlogN)的复杂度上考虑。力扣上有好多道题目是有类似字眼的,都可以使用二分解法。

二分查找

首先我们考虑一下暴力解法,我们会枚举nums1的每个位置,然后尝试用nums1其他位置的数字替换当前位置的数字,重新计算一下绝对值和,最后求一个最小值,但是时间复杂度是O(N^2),不能满足题目的要求。所以我们可以在寻找每个位置的替换数字时,可以考虑找到一个最接近nums1[i]的数字,可以使用二分查找快速找到。

  • 时间复杂度:O(NlogN),这里 N 是数组的长度。
  • 空间复杂度:O(N),使用到的临时变量的个数是常数。

三、AC 代码:

class Solution {

    /**
     * @param Integer[] $nums1
     * @param Integer[] $nums2
     * @return Integer
     */
    function minAbsoluteSumDiff($nums1, $nums2) {
        $n = count($nums1);
        $diff = 0;
        for ($i = 0; $i < $n; $i++) {
            $temp = (int)(abs($nums1[$i] - $nums2[$i]));
            $diff += $temp;
        }
        if ($diff == 0) {
            return 0;
        }
        $min = PHP_INT_MAX;
        $tempArr = $nums1;
        sort($tempArr);
        echo $diff;
        for ($i = 0; $i < $n; $i++) {
            $temp = (int)(abs($nums1[$i] - $nums2[$i]));
            if ($temp == 0) {
                continue;
            }
            $target = $nums2[$i];
            $tttt = $this->find($tempArr, 0, $n - 1, $target);
            echo $temp.':'.$target.':'.$tttt.PHP_EOL;

            $min = min($min, $diff - $temp + $tttt);
        }
        
        return $min % (1000000000 + 7);
    }

    protected function find($nums, $left, $right, $target) {
        $min = PHP_INT_MAX;
        while ($left < $right) {
            $mid = $left + (int)(($right - $left + 1) / 2);
            if ($nums[$mid] - $target > 0) {
                $right = $mid - 1;
                $min = min($min, $nums[$mid] - $target);
            } elseif ($nums[$mid] - $target < 0) {
                $left = $mid;
                $min = min($min, abs($nums[$mid] - $target));
            } else {
                return 0;
            }
        }

        return min($min, abs($nums[$left] - $target));
    }
}

四、总结:

类似的题目: 爱吃香蕉的呵呵 运送能力 做花