leetcode
leetcode 1051 ~ 1100
绝对值表达式的最大值

绝对值表达式的最大值

难度:

标签:

题目描述

代码结果

运行时间: 55 ms, 内存: 27.2 MB


/*
 * 给你两个长度相等的整数数组,返回下面表达式的最大值:
 * |arr1[i] - arr1[j]| + |arr2[i] - arr2[j]| + |i - j|
 * 其中下标 i,j 满足 0 <= i, j < arr1.length。
 *
 * 思路:
 * 1. 我们可以通过将绝对值去掉来拆分成几种情况来求解。
 * 2. 考虑六种情况,将问题简化为每种情况下找最大最小值并求差。
 */
import java.util.stream.IntStream;

public class Solution {
    public int maxAbsValExpr(int[] arr1, int[] arr2) {
        int[] max = new int[4];
        int[] min = new int[4];
        IntStream.range(0, 4).forEach(i -> {
            max[i] = Integer.MIN_VALUE;
            min[i] = Integer.MAX_VALUE;
        });
        IntStream.range(0, arr1.length).forEach(i -> {
            max[0] = Math.max(max[0], arr1[i] + arr2[i] + i);
            min[0] = Math.min(min[0], arr1[i] + arr2[i] + i);
            max[1] = Math.max(max[1], arr1[i] + arr2[i] - i);
            min[1] = Math.min(min[1], arr1[i] + arr2[i] - i);
            max[2] = Math.max(max[2], arr1[i] - arr2[i] + i);
            min[2] = Math.min(min[2], arr1[i] - arr2[i] + i);
            max[3] = Math.max(max[3], arr1[i] - arr2[i] - i);
            min[3] = Math.min(min[3], arr1[i] - arr2[i] - i);
        });
        return IntStream.range(0, 4).map(i -> max[i] - min[i]).max().getAsInt();
    }
}

解释

方法:

本题解采用了数学变换的思路。首先,将原表达式的绝对值拆解为四种情况:(arr1[i] + arr2[i] + i) - (arr1[j] + arr2[j] + j),(arr1[i] - arr2[i] + i) - (arr1[j] - arr2[j] + j),(arr1[i] - arr2[i] - i) - (arr1[j] - arr2[j] - j),(arr1[i] + arr2[i] - i) - (arr1[j] + arr2[j] - j)。对于每种情况,由于 arr1 和 arr2 的长度相等,可以遍历数组,将对应的表达式值存入四个数组 A, B, C, D 中。最后,分别计算这四个数组的最大值和最小值之差,取四者中的最大值作为结果。

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
在变换表达式时,如何保证拆分成的四种情况涵盖了所有可能的绝对值组合?
通过对绝对值运算的数学性质分析,绝对值表达式 |a - b| 可以表示为两种情况:a - b 和 b - a。在本题中,由于涉及两个数组和索引的绝对值差,表达式可展开为 |(arr1[i] + arr2[i] + i) - (arr1[j] + arr2[j] + j)| 等四种形式。这四种形式分别对应绝对值差的正负两种情况,确保涵盖了所有可能的绝对值组合。
🦆
为什么需要分别计算A, B, C, D四个数组的最大值与最小值之差?能否直接从原数组中得到这个结果?
原数组arr1和arr2的元素加上索引i产生了不同的线性表达式,这些表达式并非直接从原数组导出。计算A, B, C, D数组的最大值与最小值之差是为了找到在每种情况下可能达到的最大绝对值差。直接从原数组中计算无法直接得到这些特定线性组合的最大值差,因此需要先转换成A, B, C, D四种形式后,再求各自的最大值与最小值之差。
🦆
在计算最大值和最小值之差时,是否存在某些情况下这种方法会导致结果不准确或计算量过大?
该方法在计算最大值和最小值之差时是精确的,因为它基于数学变换准确地反映了所有可能的情况。然而,这种方法的计算量随数组长度的增加而线性增加,因为需要对每个数组进行一次完整的遍历来确定最大值和最小值。在极大数据量的情况下,这可能导致时间消耗增大,但不会影响结果的准确性。
🦆
你是如何确定将表达式拆分为(arr1[i] + arr2[i] + i)与其他三种形式的?是否有其他可能的拆分方式?
将表达式拆分为(arr1[i] + arr2[i] + i)和其他三种形式基于考虑所有可能的正负组合。这种拆分方法是为了确保每个变量(arr1[i], arr2[i], i)在表达式中以加和减的形式出现,从而涵盖所有可能的差的绝对值。虽然理论上可以有其他的拆分方式,比如将所有的组合系数变化(例如2arr1[i] - arr2[i] + 3i等),但这并不是必要的,因为基本的四种形式已经覆盖了所有情形。

相关问题