leetcode 2033. 获取单值网格的最小操作数 中等

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

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

返回使网格化为单值网格所需的 最小 操作数。如果不能,返回 -1

示例 1:

复制代码
输入:grid = [[2,4],[6,8]], x = 2
输出:4
解释:可以执行下述操作使所有元素都等于 4 : 
- 2 加 x 一次。
- 6 减 x 一次。
- 8 减 x 两次。
共计 4 次操作。

示例 2:

复制代码
输入:grid = [[1,5],[2,3]], x = 1
输出:5
解释:可以使所有元素都等于 3 。

示例 3:

复制代码
输入:grid = [[1,2],[3,4]], x = 2
输出:-1
解释:无法使所有元素相等。

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 10^5
  • 1 <= m * n <= 10^5
  • 1 <= x, grid[i][j] <= 10^4

分析:所有元素只能加减 x,因此任意两个元素之差必须是 x 的倍数,否则无法使它们相等。遍历网格,将所有元素取出放入一维数组 num,同时检查 (gridij−grid00)%x 是否等于 0。如果存在不满足的元素,直接返回 −1。

接下来先将 nums 排序。由于每次操作改变量为 x,将元素 numsi 变为目标值 t 的操作次数为
∣numsi−t∣/x,因此问题等价于最小化对所有 i 求操作次数之和。根据中位数的性质,当 t 取排序后数组的中位数时,绝对值之和最小。

cpp 复制代码
int cmp(const void *a,const void *b)
{
    return *(int*)a-*(int*)b;
}
int minOperations(int** grid, int gridSize, int* gridColSize, int x) {
    int m=gridSize,n=*gridColSize,base=grid[0][0],ans=0,t=0;
    int num[m*n+5];
    for(int i=0;i<m;++i)
    {
        for(int j=0;j<n;++j)
        {
            if((grid[i][j]-base)%x!=0)return -1;
            num[t++]=grid[i][j];
        }
    }
    qsort(num,t,sizeof(int),cmp);
    int val=num[t/2];
    for(int i=0;i<t;++i)
        ans+=abs(val-num[i])/x;

    return ans;
}
相关推荐
6Hzlia1 小时前
【Classic 150 刷题计划】 LeetCode 242. 有效的字母异位词 | C++ 哈希计数与严密防线
c++·算法·leetcode
wabs6661 小时前
关于二叉树【力扣101.对称二叉树的思考】
数据结构·c++·算法·leetcode·二叉树
6Hzlia1 小时前
【Classic 150 刷题计划】 LeetCode 228. 汇总区间 | C++ 双游标区间扫描与 to_string 规范
c++·算法·leetcode
玖玥拾2 小时前
LeetCode 383 赎金信
算法·leetcode
橘子汽水1683 小时前
Leetcode 763,45 划分字母区间 跳跃游戏II
数据结构·算法·leetcode
6Hzlia4 小时前
【Classic 150 刷题计划】 LeetCode 228. 汇总区间 | C++ 锚点游标与断点检测法
c++·算法·leetcode
Navigator_Z19 小时前
LeetCode //C - 1250. Check If It Is a Good Array
c语言·算法·leetcode
圣保罗的大教堂1 天前
leetcode 3483. 不同三位偶数的数目 简单
leetcode
mmmmath_31 天前
LeetCode.018.四数之和
数据结构·算法·leetcode