[leetcode]1131. 绝对值表达式的最大值 --绝对值表达式枚举拆分的方法

在这里插入图片描述

1、重要的数学推导:

|a| = Max(a, -a)
|a-b|+|c-d|
= Max(a-b, b-a) + Max(c-d, d-c)	  // max(a-b, -(a-b)) + max(c-d, -(c-d))
= Max{
		(a-b)+(c-d),
		(b-a)+(c-d),     // -(a - b) + (c - d)
		(a-b)+(d-c),
		(b-a)+(d-c),     // -(a - b) + (c - d) 
	}
2、对于此题就有:
|arr1[i] - arr1[j]| + |arr2[i] - arr2[j]| + |i - j|
= max(arr1[i] - arr1[j], arr1[j] - arr1[i]) + max(arr2[i] - arr2[j], arr2[j]-arr2[j]) + max(i-j, j-i)
=max{
		(arr1[i] + arr2[i] + i) - (arr1[j] + arr2[j] + j) //式1
		(arr1[i] + arr2[i] - i) - (arr1[j] + arr2[j] - j) //式2
		(arr1[i] - arr2[i] + i) - (arr1[j] - arr2[j] + j) //式3
		(arr1[i] - arr2[i] - i) - (arr1[j] - arr2[j] - j) //式4
		-(arr1[i] + arr2[i] + i) + (arr1[j] + arr2[j] + j)//式5
		-(arr1[i] + arr2[i] - i) + (arr1[j] + arr2[j] - j)//式6
		-(arr1[i] - arr2[i] + i) + (arr1[j] - arr2[j] + j)//式7
		-(arr1[i] - arr2[i] - i) + (arr1[j] - arr2[j] - j)//式8
    }

设:

A = arr1[i] + arr2[i] + i
B = arr1[i] + arr2[i] - i
C = arr1[i] - arr2[i] + i
D = arr1[i] - arr2[i] - i

因为我们要求绝对值表达式的最大值,所以对于上面的表达式,每个表达式都应取最大值,就是说只有让前面符号是正的最大,前面符号是负的最小才行,这样就能O(n)算出绝对值表达式的最大值了

|arr1[i] - arr1[j]| + |arr2[i] - arr2[j]| + |i - j|
=max(	
		max(A) - min(A),
		max(B) - min(B),
		max(C) - min(C),
		max(D) - min(D),
		-min(A) + max(A),
		-min(B) + max(B),
		-min(C) + max(C),
		-min(C) + max(C)
	)

实现代码:

class Solution {
public:
    int maxAbsValExpr(vector<int>& arr1, vector<int>& arr2) {
        int f[8][3] = { { 1, 1, 1}, { 1, -1, 1}, { 1,-1,-1}, {1,1,-1},
                        {-1, 1, 1}, {-1, -1, 1}, {-1, 1,-1}, {-1,-1,-1}};
        int ans = INT_MIN;
        for(int k = 0; k < 8; k++)
        {
            int mx = INT_MIN;
            int mi = INT_MAX;
            for(int i = 0; i < arr1.size(); i++)
            {
                mx = max(mx, arr1[i]*f[k][0] + arr2[i]*f[k][1] + i*f[k][2]);
                mi = min(mi, arr1[i]*f[k][0] + arr2[i]*f[k][1] + i*f[k][2]);
            }
            ans = max(ans, mx - mi);
        }
        return ans;
    }
};

当然上面其实是有重复的。如: max(A) - min(A) == -min(A) + max(A)
所以可以改成这样:

class Solution {
public:
    int maxAbsValExpr(vector<int>& arr1, vector<int>& arr2) {
        int f[4][3] = { { 1, 1, 1}, { 1, -1, 1}, { 1,-1,-1}, {1,1,-1}};
        int ans = INT_MIN;
        for(int k = 0; k < 4; k++)
        {
            int mx = INT_MIN;
            int mi = INT_MAX;
            for(int i = 0; i < arr1.size(); i++)
            {
                mx = max(mx, arr1[i]*f[k][0] + arr2[i]*f[k][1] + i*f[k][2]);
                mi = min(mi, arr1[i]*f[k][0] + arr2[i]*f[k][1] + i*f[k][2]);
            }
            ans = max(ans, mx - mi);
        }
        return ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值