给你一个大小为 m x n 的二维整数网格 grid 和一个整数 x 。每一次操作,你可以对 grid 中的任一元素 加 x 或 减 x 。
单值网格 是全部元素都相等的网格。
返回使网格化为单值网格所需的 最小 操作数。如果不能,返回 -1 。

- 先将二维数组转换为一维数组。设数组 a a a,满足 a [ i ∗ m + j ] = g r i d [ i ] [ j ] a[i * m + j] = grid[i][j] a[i∗m+j]=grid[i][j]
- 设数组b,存操作序列。表示对于每个元素执行 a [ i ] ∗ b [ i ] ∗ x a[i] * b[i] * x a[i]∗b[i]∗x
于是优化目标为
m
i
n
∑
i
∣
b
[
i
]
∣
min \quad \sum_{i}|b[i]|
mini∑∣b[i]∣
s
.
t
.
a
[
i
]
+
b
[
i
]
∗
x
=
a
[
j
]
+
b
[
j
]
∗
x
∀
i
,
j
s.t. \quad a[i] + b[i] * x = a[j] + b[j]*x\quad \forall i,j
s.t.a[i]+b[i]∗x=a[j]+b[j]∗x∀i,j
约束条件等价于
b
[
j
]
=
b
[
i
]
−
a
[
i
]
−
a
[
j
]
x
∀
i
,
j
b[j] = b[i] - \frac{a[i] - a[j]}{x} \quad \forall i,j
b[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
=
0
i = 0
i=0(因为后面的约束都是冗余的)得到
b
[
j
]
=
b
[
0
]
−
a
[
0
]
−
a
[
j
]
x
b[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}|
j∑∣b[0]−xa[0]−a[j]∣
这里
a
[
0
]
,
a
[
j
]
,
x
a[0],a[j],x
a[0],a[j],x都是已知的。该形式就是初中学过的找一个点(在这里这些点就是
a
[
0
]
−
a
[
j
]
x
\frac{a[0]-a[j]}{x}
xa[0]−a[j]),使得绝对值距离最小的问题。一般地,选取这个点为所有点的中位数即可。
此类问题的一般形式如下:
m
i
n
∣
x
−
a
1
∣
+
∣
x
−
a
2
∣
+
⋯
+
∣
x
−
a
n
∣
min \quad |x - a_1| + |x - a_2| + \cdots + |x - a_n|
min∣x−a1∣+∣x−a2∣+⋯+∣x−an∣
此类问题的解为点列
a
1
,
a
2
,
⋯
a
n
a_1,a_2,\cdots a_n
a1,a2,⋯an的中位数。
当点列个数为偶数时,可以使用绝对值不等式证明这个结论。不妨设
a
1
,
a
2
⋯
a
n
a_1,a_2\cdots a_n
a1,a2⋯an升序排列,如果不是升序排列,将其排序使其是升序。则:
∣
x
−
a
1
∣
+
∣
x
−
a
2
∣
+
⋯
+
∣
x
−
a
n
∣
=
∣
x
−
a
1
∣
+
∣
x
−
a
2
∣
+
⋯
+
∣
x
−
a
n
2
∣
+
∣
a
n
2
+
1
−
x
∣
+
⋯
∣
a
n
−
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|
∣x−a1∣+∣x−a2∣+⋯+∣x−an∣=∣x−a1∣+∣x−a2∣+⋯+∣x−a2n∣+∣a2n+1−x∣+⋯∣an−x∣
由绝对值不等式得到:
∣
x
−
a
1
∣
+
∣
x
−
a
2
∣
+
⋯
+
∣
x
−
a
n
2
∣
+
∣
a
n
2
+
1
−
x
∣
+
⋯
∣
a
n
−
x
∣
≥
∣
x
−
a
1
+
⋯
x
−
a
n
2
+
a
n
2
+
1
−
x
+
⋯
+
a
n
−
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|
∣x−a1∣+∣x−a2∣+⋯+∣x−a2n∣+∣a2n+1−x∣+⋯∣an−x∣≥∣x−a1+⋯x−a2n+a2n+1−x+⋯+an−x∣
上述式子右侧的x恰好完全被抵消了,只剩下常数项。上述式子可以取等号的条件是绝对值里的元素是同号的,假设是同正的,则有:
x
≥
a
1
,
x
≥
a
2
,
⋯
x
≥
a
n
2
x \geq a_1,x\geq a_2,\cdots x\geq a_{\frac{n}{2}}
x≥a1,x≥a2,⋯x≥a2n
x
≤
a
n
2
+
1
,
⋯
x
≤
a
n
x \leq a_{\frac{n}{2}+1},\cdots x \leq a_{n}
x≤a2n+1,⋯x≤an
显然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;
}
}
最小操作数转化为单值网格
这篇博客探讨了一个二维整数网格转化为单值网格的优化问题,通过一系列加减x的操作。首先将二维数组转为一维,然后寻找一个基准值,并计算每个元素与基准值的差值对x取模的结果。如果所有结果相同,说明可以转化为单值网格,否则返回-1。优化目标是最小化操作次数,即找到一个点使得所有元素到该点的绝对距离之和最小,证明了取中位数可以达到最优解。最后给出了AC代码实现。
2084

被折叠的 条评论
为什么被折叠?



