class Solution {
public:
int minOperations(vector<vector<int>>& grid, int x) {
}
};
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 <= 105
1 <= m * n <= 105
1 <= x, grid[i][j] <= 104
原站题解
python3 解法, 执行用时: 264 ms, 内存消耗: 37 MB, 提交时间: 2023-09-17 12:11:44
class Solution: def minOperations(self, grid, x): line, col, ret, li = len(grid), len(grid[0]), 0, [] for i in grid: li.extend(i) li.sort() mid = li[len(li) // 2] for v in li: if abs(mid - v) % x: return -1 ret += abs(mid - v) // x return ret
javascript 解法, 执行用时: 280 ms, 内存消耗: 68.7 MB, 提交时间: 2023-09-17 12:11:16
/** * @param {number[][]} grid * @param {number} x * @return {number} */ var minOperations = (grid, x) => { // 行、列 const [m, n] = [grid.length, grid[0].length]; // 如果只有一个元素,返回0 if (m === 1 && n === 1) return 0; // 将网格扁平化 const nums = []; for (let i = 0; i < m; i++) { nums.push(...grid[i]); } // 升序排序 nums.sort((a, b) => a - b); const numsLen = nums.length; // 中位数 const num = nums[numsLen >> 1]; let res = 0; for (let i = 0; i < numsLen; i++) { // 当前数和中位数的差值 const gap = nums[i] - num; // 某个差值不是x的倍数,则不能完成操作 if (gap % x) return -1; // 累加上步骤次数 res += (gap > 0 ? gap : -gap) / x; } return res; };
java 解法, 执行用时: 36 ms, 内存消耗: 68.5 MB, 提交时间: 2023-09-17 12:10:51
class Solution { public int minOperations(int[][] grid, int x) { int n = grid.length; int m = grid[0].length; int[] arr = new int[m*n]; int i = 0; for(int[] a : grid) for(int a_ : a){ arr[i++] = a_; } Arrays.sort(arr); int j = arr[(n*m)/2]; int sum = 0; for(int a : arr){ int l = Math.abs(j-a); if(l%x != 0) return -1; sum += l/x; } return sum; } }
golang 解法, 执行用时: 220 ms, 内存消耗: 13.8 MB, 提交时间: 2023-09-17 12:10:20
/** * 要使任意两元素最终相等,这两元素的差必须是 x 的倍数,否则无法通过加减 x 来相等。 * 我们可以以数组中的某一元素为基准,若所有元素与它的差均为 x 的倍数,则任意两元素之差为 x 的倍数。 * 所以贪心的做法就是取所有元素的中位数 */ func minOperations(grid [][]int, x int) (ans int) { n := len(grid) * len(grid[0]) a := make([]int, 0, n) for _, row := range grid { for _, v := range row { if (v-grid[0][0])%x != 0 { // 以其中一元素为基准,若所有元素与它的差均为 x 的倍数,则任意两元素之差为 x 的倍数 return -1 } } a = append(a, row...) } sort.Ints(a) // 除了排序,也可以用求第 k 大算法来找中位数 for _, v := range a { ans += abs(v-a[n/2]) / x } return } func abs(x int) int { if x < 0 { return -x } return x }