列表

详情


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
解释:无法使所有元素相等。

 

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: int minOperations(vector<vector<int>>& grid, int x) { } };

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
}

上一题