Description
You are given a 2D integer grid of size m x n and an integer x. In one operation, you can add x to or subtract x from any element in the grid.
A uni-value grid is a grid where all the elements of it are equal.
Return the minimum number of operations to make the grid uni-value. If it is not possible, return -1.
Example 1:
Input: grid = [[2,4],[6,8]], x = 2 Output: 4 Explanation: We can make every element equal to 4 by doing the following: - Add x to 2 once. - Subtract x from 6 once. - Subtract x from 8 twice. A total of 4 operations were used.
Example 2:
Input: grid = [[1,5],[2,3]], x = 1 Output: 5 Explanation: We can make every element equal to 3.
Example 3:
Input: grid = [[1,2],[3,4]], x = 2 Output: -1 Explanation: It is impossible to make every element equal.
Constraints:
m == grid.lengthn == grid[i].length1 <= m, n <= 1051 <= m * n <= 1051 <= x, grid[i][j] <= 104
Solutions
This optimized version pre-allocates an array with a known size (m * n) and flattens the grid by directly assigning values to calculated indices, avoiding intermediate object creation. Like the previous solution, it validates that all values share the same remainder modulo x, then determines the optimal median target. The key difference is that countOperations now works directly on the sorted array rather than repeatedly iterating through the original grid, making it more efficient for multiple median candidate evaluations.
/**
* @param {number[][]} grid
* @param {number} x
* @return {number}
*/
var minOperations = function(grid, x) {
const m = grid.length;
const n = grid[0].length;
const arr = Array(m * n);
const rem = grid[0][0] % x;
for (let row = 0; row < m; row++) {
for (let col = 0; col < n; col++) {
if (grid[row][col] % x !== rem) {
return -1;
}
arr[row * n + col] = grid[row][col];
}
}
arr.sort((a, b) => a - b);
const mid = Math.floor(arr.length / 2);
if ((arr.length & 1) || arr[mid - 1] === arr[mid]) {
return countOperations(arr, x, arr[mid]);
}
return Math.min(
countOperations(arr, x, arr[mid - 1]),
countOperations(arr, x, arr[mid]),
);
};
const countOperations = (arr, x, target) => {
let operations = 0;
for (const val of arr) {
operations += Math.round(Math.abs(target - val) / x);
}
return operations;
};