LeetCode 2033. 获取单值网格的最小操作数【详细技术解析】
2026/4/28 12:46:23 网站建设 项目流程

LeetCode 2033. 获取单值网格的最小操作数【详细技术解析】

一、题目描述

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

单值网格:指网格中全部元素都相等的网格。

要求返回使网格化为单值网格所需的最小操作数。如果无法实现,返回\-1

题目示例

示例 1:

输入:grid = [[2,4],[6,8]], x = 2

输出:4

解释:将所有元素统一为 4。2+2(1次)、6-2(1次)、8-2*2(2次),总操作数 4。

示例 2:

输入:grid = [[1,5],[2,3]], x = 1

输出:5

解释:将所有元素统一为 3,累计操作次数最少为5。

示例 3:

输入:grid = [[1,2],[3,4]], x = 2

输出:-1

解释:元素差值无法被x整除,无法统一为相同值。

题目约束

  • m == grid\.lengthn == grid\[i\]\.length

  • 1 \<= m, n \<= 10^5

  • 1 \<= m \* n \<= 10^5(总元素数不超过10万,时间复杂度可接受O(NlogN))

  • 1 \<= x, grid\[i\]\[j\] \<= 10^4

二、核心解题思路分析

1. 可行性判断(关键前提)

每次操作只能对元素加x/减x,因此任意两个元素的差值,必须是x的整数倍,否则永远无法通过操作使所有元素相等。

推导:假设基准值为target,任意元素num满足\(num \- target\) % x == 0。可等价推导为:所有元素对 x 的余数必须完全相同

若存在任意元素的余数与首个元素余数不同,直接返回\-1

2. 最小操作数的数学原理

当所有元素可统一时,问题转化为:寻找一个目标值,使所有元素转换到该值的操作次数总和最小

操作次数公式:单个元素num转为target的操作次数 =abs\(num \- target\) // x

根据绝对值距离最小值定理:一组有序数字中,所有数字到中位数的绝对值距离之和最小。因此最优目标值为数组的中位数。

3. 整体解题步骤

  1. 将二维网格展平为一维数组,方便统一处理;

  2. 遍历数组,校验所有元素对x的余数是否一致,不一致直接返回-1;

  3. 对一维数组进行排序,找到中位数;

  4. 遍历所有元素,累计转换到中位数的总操作次数,返回结果。

三、完整代码实现(带详细注释)

严格遵循题目要求的代码格式,适配LeetCode提交标准,包含完整注释、边界处理:

fromtypingimportListclassSolution:defminOperations(self,grid:List[List[int]],x:int)->int:# 1. 将二维网格展平为一维数组nums=[]forrowingrid:nums.extend(row)# 2. 获取首个元素的余数,作为校验基准remainder=nums[0]%x# 3. 遍历所有元素,校验余数是否统一fornuminnums:ifnum%x!=remainder:# 余数不统一,无法构成单值网格return-1# 4. 数组排序,寻找中位数nums.sort()mid=len(nums)//2target=nums[mid]# 5. 计算所有元素转换为中位数的最小操作次数res=0fornuminnums:# 差值整除x即为当前元素需要的操作次数res+=abs(num-target)//xreturnres

四、代码优化版本(精简高效)

在不改变时间复杂度的前提下,精简代码逻辑,减少冗余遍历,适配大数据量场景:

fromtypingimportListclassSolution:defminOperations(self,grid:List[List[int]],x:int)->int:# 一行代码展平二维数组nums=[numforrowingridfornuminrow]base_mod=nums[0]%x# 合法性校验ifany(num%x!=base_modfornuminnums):return-1# 排序取中位数,计算总操作数nums.sort()median=nums[len(nums)//2]returnsum(abs(n-median)//xforninnums)

五、逐案例代码解析

案例1:grid = [[2,4],[6,8]], x = 2

1. 展平数组:\[2,4,6,8\],基准余数2%2=0,所有元素余数均为0,合法;

2. 排序后数组不变,长度为4,中位数下标为2,目标值6?修正:长度4,下标4//2=2,元素为6,也可选取4,两者总操作数一致;

3. 计算次数:|2-4|/2 + |4-4|/2 + |6-4|/2 + |8-4|/2 = 1+0+1+2 = 4,与输出结果一致。

案例3:grid = [[1,2],[3,4]], x = 2

1. 展平数组:\[1,2,3,4\],基准余数1%2=1

2. 元素2%2=0,余数不匹配,直接返回-1,符合题意。

六、复杂度分析

时间复杂度:O(N log N)

N 为网格总元素数(N = m\*n)。主要耗时为数组排序操作,时间复杂度为 O(N log N);两次遍历数组为 O(N),可忽略。根据题目约束 N ≤ 10^5,该复杂度完全AC。

空间复杂度:O(N)

需要额外一维数组存储所有网格元素,空间复杂度为元素总数 N。若允许修改原数组,可原地优化,但可读性会下降。

七、易错点总结

  • 易错点1:直接使用平均值作为目标值。平均值适用于平方和最小,而本题是绝对值和最小,必须使用中位数,否则会导致结果错误。

  • 易错点2:仅校验首尾元素差值,未校验所有元素余数。必须保证全部元素余数一致,否则存在无法统一的元素。

  • 易错点3:使用浮点数计算操作次数。必须用整数整除//,避免浮点精度误差。

八、总结

本题是数学贪心+数组排序的经典题型,核心考点分为两点:一是通过余数校验判断问题可行性,二是利用中位数的数学性质求解最小操作次数。解题逻辑清晰,代码简洁,是算法面试中高频的简单贪心题型,熟练掌握中位数最值原理即可快速解题。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询