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.

&nbsp;
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.


&nbsp;
Constraints:


	m == grid.length
	n == grid[i].length
	1 &lt;= m, n &lt;= 105
	1 &lt;= m * n &lt;= 105
	1 &lt;= x, grid[i][j] &lt;= 104


class Solution:
    def minOperations(self, grid: List[List[int]], x: int) -> int:
        
        m = len(grid)
        n = len(grid[0])
		
		# handle the edge case
        if m==1 and n==1: return 0
		
		# transform grid to array, easier to operate
        arr = [] 
        for i in range(m):
            arr+=grid[i]
        
        arr.sort()
        
		# the median is arr[len(arr)//2] when len(arr) is odd
		# or may be arr[len(arr)//2] and arr[len(arr)//2-1] when len(arr) is even.
        cand1 = arr[len(arr)//2]
        cand2 = arr[len(arr)//2-1]
        
        return min(
            self.get_num_operations_to_target(grid, cand1, x),
            self.get_num_operations_to_target(grid, cand2, x)
        )
        
        
    def get_num_operations_to_target(self, grid, target,x):
		"""Get the total number of operations to transform all grid elements to the target value."""
        ans = 0
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if abs(grid[i][j]-target)%x!=0:
                    return -1
                else:
                    ans+=abs(grid[i][j]-target)//x

        return ans
                
class Solution {
    public int minOperations(int[][] grid, int x) {
        int[] arr = new int[grid.length * grid[0].length];
        int index = 0;
        
        for (int i = 0; i < grid.length; i++) {
            for (int j = 0; j < grid[0].length; j++) {
                arr[index++] = grid[i][j];
            }
        }
        
        Arrays.sort(arr);
        int median = arr[(arr.length - 1) / 2];
        int steps = 0;
        
        for (int num : arr) {
            if (num == median) {
                continue;
            }
            
            if (Math.abs(num - median) % x != 0) {
                return -1;
            }
            
            steps += (Math.abs(num - median) / x);
        }
        
        return steps;
    }
}
class Solution {
public:
    int minOperations(vector<vector<int>>& grid, int x) {
        vector<int>nums;
        int m=grid.size(),n=grid[0].size();
        for(int i=0;i<m;i++)
            for(int j=0;j<n;j++)
                nums.push_back(grid[i][j]);
        sort(nums.begin(),nums.end());
        int target=nums[m*n/2],ans=0;
        for(int i=m*n-1;i>=0;i--){
            if(abs(nums[i]-target)%x!=0)
                return -1;
            else
                ans+=abs(nums[i]-target)/x;  
        }
        return ans;
    }
};
var minOperations = function(grid, x) {
    
    let remainder = -Infinity, flatten = [], res = 0;
    
    for(let i = 0;i<grid.length;i++){
        for(let j = 0;j<grid[i].length;j++){
            
            if(remainder === -Infinity)
                remainder = grid[i][j] % x;
            else if(remainder !== grid[i][j] % x){
                return -1;
            }
            flatten.push(grid[i][j])
        }
    }
    flatten.sort((a,b)=> a-b);
    let median = flatten[~~(flatten.length/2)] 

    for(let i = 0;i<flatten.length;i++){
        res += Math.abs(flatten[i] - median) / x
    }
    return res;
};
Minimum Operations to Make a Uni-Value Grid