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

123 阅读1分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动

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

给你一个大小为 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 解释:无法使所有元素相等。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OPQq06WR-1633852216823)(https://pic.leetcode-cn.com/1633851802-lVimlL-1633851797(1)].png)

解题思路

因为单值网格是来源于网格中元素加 x 或 减 x 。因此单值元素必然来源于grid 中的任一元素加减x的倍数,也grid中的每个元素之间也相差x的倍数。所以我们可以选择grid中的任意元素作为最后的单值。但是题目需要我们求出最小操作数,因此我们需要选择出grid的中位数作为最后的单值

代码

class Solution {

     public int minOperations(int[][] grid, int x) {
        int n = grid.length, m = grid[0].length;
        int min = grid[0][0],sum=0;
        List<Integer> mid = new ArrayList<>();
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                if ((grid[i][j] - min) % x != 0)
                    return -1;
                else mid.add(grid[i][j]);
        Collections.sort(mid);
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                sum+=Math.abs(grid[i][j]-mid.get(n*m/2))/x;
        return sum;
    }
}