Description
You are given an n x n integer matrix. You can do the following operation any number of times:
- Choose any two adjacent elements of
matrixand multiply each of them by-1.
Two elements are considered adjacent if and only if they share a border.
Your goal is to maximize the summation of the matrix's elements. Return the maximum sum of the matrix's elements using the operation mentioned above.
Example 1:
Input: matrix = [[1,-1],[-1,1]] Output: 4 Explanation: We can follow the following steps to reach sum equals 4: - Multiply the 2 elements in the first row by -1. - Multiply the 2 elements in the first column by -1.
Example 2:
Input: matrix = [[1,2,3],[-1,-2,-3],[1,2,3]] Output: 16 Explanation: We can follow the following step to reach sum equals 16: - Multiply the 2 last elements in the second row by -1.
Constraints:
n == matrix.length == matrix[i].length2 <= n <= 250-105 <= matrix[i][j] <= 105
Solutions
This final version fixes the earlier mistake by tracking the right value to sacrifice. In a single O(m × n) pass it adds every cell's magnitude to total (treating each value as if it could be made positive), counts non-positive entries in negativeCounter, and — crucially — records the smallest absolute value across the whole matrix in smallestNumber, checking Math.abs(matrix[r][c]) for every cell rather than only the negative ones. Because the allowed operation flips two adjacent values at once, an even number of negatives can always be cancelled completely; if the bitwise test negativeCounter & 1 reveals an odd count, exactly one value must end up negative, and the cheapest choice is the one with the smallest magnitude, so smallestNumber * 2 is subtracted (its contribution swings from positive to negative). This greedy approach solves the problem in one pass with constant extra space.
/**
* @param {number[][]} matrix
* @return {number}
*/
var maxMatrixSum = function(matrix) {
const m = matrix.length;
const n = matrix[0].length;
let total = 0;
let negativeCounter = 0;
let smallestNumber = Infinity;
for (let r = 0; r < m; r++) {
for (let c = 0; c < n; c++) {
if (matrix[r][c] > 0) {
total += matrix[r][c];
} else {
total += -matrix[r][c];
negativeCounter++;
}
smallestNumber = Math.min(smallestNumber, Math.abs(matrix[r][c]));
}
}
if (negativeCounter & 1) {
total -= smallestNumber * 2;
}
return total;
};