leetcode 获取单值网格的最小操作数

这篇博客探讨了一个二维整数网格转化为单值网格的优化问题,通过一系列加减x的操作。首先将二维数组转为一维,然后寻找一个基准值,并计算每个元素与基准值的差值对x取模的结果。如果所有结果相同,说明可以转化为单值网格,否则返回-1。优化目标是最小化操作次数,即找到一个点使得所有元素到该点的绝对距离之和最小,证明了取中位数可以达到最优解。最后给出了AC代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

给你一个大小为 m x n 的二维整数网格 grid 和一个整数 x 。每一次操作,你可以对 grid 中的任一元素 加 x 或 减 x 。

单值网格 是全部元素都相等的网格。

返回使网格化为单值网格所需的 最小 操作数。如果不能,返回 -1 。
在这里插入图片描述

  • 先将二维数组转换为一维数组。设数组aaa,满足a[i∗m+j]=grid[i][j]a[i * m + j] = grid[i][j]a[im+j]=grid[i][j]
  • 设数组b,存操作序列。表示对于每个元素执行a[i]∗b[i]∗xa[i] * b[i] * xa[i]b[i]x

于是优化目标为
min∑i∣b[i]∣min \quad \sum_{i}|b[i]|minib[i]
s.t.a[i]+b[i]∗x=a[j]+b[j]∗x∀i,js.t. \quad a[i] + b[i] * x = a[j] + b[j]*x\quad \forall i,js.t.a[i]+b[i]x=a[j]+b[j]xi,j

约束条件等价于
b[j]=b[i]−a[i]−a[j]x∀i,jb[j] = b[i] - \frac{a[i] - a[j]}{x} \quad \forall i,jb[j]=b[i]xa[i]a[j]i,j
显然约束条件成立的充分必要条件是
(a[i]−a[j])%x=0(a[i] -a[j]) \% x= 0(a[i]a[j])%x=0
固定i=0i = 0i=0(因为后面的约束都是冗余的)得到b[j]=b[0]−a[0]−a[j]xb[j] = b[0] - \frac{a[0]-a[j]}{x}b[j]=b[0]xa[0]a[j]
于是原约束问题变成了无约束优化问题
∑j∣b[0]−a[0]−a[j]x∣\sum_{j} |b[0] - \frac{a[0]-a[j]}{x}|jb[0]xa[0]a[j]
这里a[0],a[j],xa[0],a[j],xa[0],a[j],x都是已知的。该形式就是初中学过的找一个点(在这里这些点就是a[0]−a[j]x\frac{a[0]-a[j]}{x}xa[0]a[j]),使得绝对值距离最小的问题。一般地,选取这个点为所有点的中位数即可。

此类问题的一般形式如下:
min∣x−a1∣+∣x−a2∣+⋯+∣x−an∣min \quad |x - a_1| + |x - a_2| + \cdots + |x - a_n|minxa1+xa2++xan
此类问题的解为点列a1,a2,⋯ana_1,a_2,\cdots a_na1,a2,an的中位数。
当点列个数为偶数时,可以使用绝对值不等式证明这个结论。不妨设a1,a2⋯ana_1,a_2\cdots a_na1,a2an升序排列,如果不是升序排列,将其排序使其是升序。则:
∣x−a1∣+∣x−a2∣+⋯+∣x−an∣=∣x−a1∣+∣x−a2∣+⋯+∣x−an2∣+∣an2+1−x∣+⋯∣an−x∣ |x - a_1| + |x - a_2| + \cdots + |x - a_n| = |x-a_1| + |x-a_2| + \cdots + |x - a_{\frac{n}{2}}| + |a_{\frac{n}{2}+1} - x| + \cdots |a_n - x|xa1+xa2++xan=xa1+xa2++xa2n+a2n+1x+anx
由绝对值不等式得到:
∣x−a1∣+∣x−a2∣+⋯+∣x−an2∣+∣an2+1−x∣+⋯∣an−x∣≥∣x−a1+⋯x−an2+an2+1−x+⋯+an−x∣ |x-a_1| + |x-a_2| + \cdots + |x - a_{\frac{n}{2}}| + |a_{\frac{n}{2}+1} - x| + \cdots |a_n - x| \geq |x-a_1 + \cdots x-a_{\frac{n}{2}} + a_{\frac{n}{2}+1} -x + \cdots +a_n -x|xa1+xa2++xa2n+a2n+1x+anxxa1+xa2n+a2n+1x++anx
上述式子右侧的x恰好完全被抵消了,只剩下常数项。上述式子可以取等号的条件是绝对值里的元素是同号的,假设是同正的,则有:
x≥a1,x≥a2,⋯x≥an2x \geq a_1,x\geq a_2,\cdots x\geq a_{\frac{n}{2}}xa1,xa2,xa2n
x≤an2+1,⋯x≤anx \leq a_{\frac{n}{2}+1},\cdots x \leq a_{n}xa2n+1,xan
显然x可以取序列的中位数使得上述式子成立。
对于奇数点,可以证明也是当取得中位数时上述式子最小。AC代码如下:

class Solution {
    public int minOperations(int[][] grid, int x) {
        int[] a = new int[grid.length * grid[0].length];
        for(int i = 0;i<grid.length;i++)
        {
            for(int j = 0;j<grid[0].length;j++)
                a[i * grid[0].length + j] = grid[i][j];
        }
        int[] coffeient = new int[a.length];
        coffeient[0] = 0;
        int min = coffeient[0];
        int Max = coffeient[0];
        for(int i = 1;i<coffeient.length;i++)
        {
            if((a[i] - a[0]) % x != 0)
                return -1;
            coffeient[i] = (a[i] - a[0]) /x;
        }
        int ans = 0;
        Arrays.sort(coffeient);
        int zhi = coffeient[coffeient.length  /2];
        for(int i = 0;i<coffeient.length;i++)
        {
            ans += Math.abs(coffeient[i] - zhi);
        }
        return ans;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值