Facebook Pixel

1975. Maximum Matrix Sum

Problem Description

You have an n x n integer matrix, and you can perform a special operation as many times as you want. The operation allows you to pick any two adjacent elements in the matrix (elements that share a border - horizontally or vertically next to each other) and multiply both of them by -1. This flips the sign of both elements simultaneously.

Your task is to find the maximum possible sum of all elements in the matrix after performing this operation any number of times (including zero times).

For example, if you have two adjacent elements [3, -5], after applying the operation once, they become [-3, 5]. The key insight is that this operation always flips the signs of exactly two elements at once.

The solution uses a greedy approach based on counting negative numbers. Since each operation flips two signs at once, if you have an even number of negative elements, you can make all elements positive. If you have an odd number of negative elements, exactly one element must remain negative in the final configuration. In this case, you'd want the negative element to be the one with the smallest absolute value to maximize the total sum.

The code tracks:

  • cnt: the count of negative numbers
  • mi: the minimum absolute value among all elements
  • s: the sum of absolute values of all elements

If cnt is even, all elements can be made positive, so return s. If cnt is odd, one element must stay negative, so return s - 2 * mi (subtracting the smallest absolute value twice accounts for removing it from the positive sum and adding it as negative).

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

Let's think about what happens when we apply the operation. Each operation flips the signs of exactly two adjacent elements. This means:

  1. If both elements are positive, they become negative (sum decreases)
  2. If both elements are negative, they become positive (sum increases)
  3. If one is positive and one is negative, they swap signs (sum may increase or decrease)

The key observation is that each operation changes the parity of negative numbers by either 0 or 2. If we start with an even number of negative elements, we'll always have an even number after any operation. Similarly, if we start with odd, we'll always have odd.

Now, what's the best possible outcome? Ideally, we want all elements to be positive to maximize the sum. Can we achieve this?

  • If we have an even number of negative elements: Yes! We can pair them up and flip each pair to positive.
  • If we have an odd number of negative elements: No matter how we operate, we'll always have an odd number, meaning at least one must remain negative.

For the odd case, which element should remain negative? To maximize the sum, we want to minimize the loss, so we should keep the element with the smallest absolute value as negative.

This leads us to the strategy:

  1. Count the negative numbers to determine parity
  2. Find the element with minimum absolute value (in case we need to keep one negative)
  3. Calculate the sum of all absolute values
  4. If odd number of negatives, subtract twice the minimum absolute value (once to remove it from the positive sum, once to add it as negative)

This greedy approach works because the operation gives us enough flexibility to rearrange signs optimally while respecting the parity constraint.

Learn more about Greedy patterns.

Solution Approach

The implementation follows a greedy strategy based on the parity of negative numbers in the matrix.

Algorithm Steps:

  1. Initialize tracking variables:

    • mi = inf: Track the minimum absolute value across all elements
    • s = 0: Accumulate the sum of absolute values
    • cnt = 0: Count the number of negative elements
  2. Single pass through the matrix:

    for row in matrix:
        for x in row:

    For each element x:

    • Count negative numbers: cnt += x < 0 (adds 1 if negative, 0 if non-negative)
    • Calculate absolute value: y = abs(x)
    • Update minimum absolute value: mi = min(mi, y)
    • Add to total sum: s += y
  3. Determine final result based on parity:

    return s if cnt % 2 == 0 else s - mi * 2
    • If cnt % 2 == 0 (even number of negatives): All elements can be made positive, return s
    • If cnt % 2 == 1 (odd number of negatives): One element must remain negative
      • We subtract mi * 2 from s because:
        • We already added mi to s as positive
        • We need to remove it (-mi) and add it as negative (-mi)
        • Total adjustment: -2 * mi

Time Complexity: O(nΒ²) where n is the dimension of the matrix, as we visit each element once.

Space Complexity: O(1) as we only use a constant amount of extra space for variables.

The elegance of this solution lies in recognizing that we don't need to simulate the actual operations. We only need to determine the final configuration based on the parity constraint and greedily choose the optimal element to remain negative if needed.

Ready to land your dream job?

Unlock your dream job with a 5-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through a concrete example with a 2x2 matrix:

Initial matrix: [[2, -3],
                 [-5, 4]]

Step 1: Analyze the initial state

  • Count negative numbers: 2 (the -3 and -5)
  • Calculate absolute values: [[2, 3], [5, 4]]
  • Sum of absolute values: 2 + 3 + 5 + 4 = 14
  • Minimum absolute value: 2

Step 2: Determine what's possible Since we have 2 negative numbers (even count), we can make all elements positive through operations.

Step 3: Demonstrate how to achieve all positive (for understanding)

  • Apply operation on -3 and -5 (they're adjacent vertically):
    [[2, -3],     β†’     [[2, 3],
     [-5, 4]]            [5, 4]]
  • Now all elements are positive! Sum = 2 + 3 + 5 + 4 = 14

Step 4: Apply our algorithm

  • cnt = 2 (even)
  • s = 14 (sum of absolute values)
  • mi = 2 (minimum absolute value)
  • Since cnt is even: return s = 14

Now let's try an example with odd negatives:

Initial matrix: [[1, -2],
                 [3, 4]]

Step 1: Analyze

  • Count negative numbers: 1 (only -2)
  • Sum of absolute values: 1 + 2 + 3 + 4 = 10
  • Minimum absolute value: 1

Step 2: Determine what's possible With 1 negative number (odd count), we must keep exactly one element negative after all operations.

Step 3: Find optimal configuration We want the smallest absolute value (1) to be negative to minimize loss:

  • Apply operation on 1 and -2:
    [[1, -2],     β†’     [[-1, 2],
     [3, 4]]              [3, 4]]
  • Final sum = -1 + 2 + 3 + 4 = 8

Step 4: Apply our algorithm

  • cnt = 1 (odd)
  • s = 10 (sum of absolute values)
  • mi = 1 (minimum absolute value)
  • Since cnt is odd: return s - 2mi = 10 - 21 = 8

The algorithm correctly identifies that with an odd number of negatives, we lose 2 Γ— (minimum absolute value) from the maximum possible sum.

Solution Implementation

1class Solution:
2    def maxMatrixSum(self, matrix: List[List[int]]) -> int:
3        # Track the smallest absolute value in the matrix
4        min_absolute_value = float('inf')
5      
6        # Track the sum of absolute values and count of negative numbers
7        total_absolute_sum = 0
8        negative_count = 0
9      
10        # Iterate through all elements in the matrix
11        for row in matrix:
12            for value in row:
13                # Count negative numbers
14                if value < 0:
15                    negative_count += 1
16              
17                # Get absolute value of current element
18                absolute_value = abs(value)
19              
20                # Update minimum absolute value seen so far
21                min_absolute_value = min(min_absolute_value, absolute_value)
22              
23                # Add to total sum of absolute values
24                total_absolute_sum += absolute_value
25      
26        # If even number of negatives, we can make all values positive
27        # If odd number of negatives, one value must remain negative (choose the smallest)
28        if negative_count % 2 == 0:
29            return total_absolute_sum
30        else:
31            return total_absolute_sum - 2 * min_absolute_value
32
1class Solution {
2    public long maxMatrixSum(int[][] matrix) {
3        // Total sum of absolute values
4        long totalSum = 0;
5      
6        // Track the minimum absolute value in the matrix
7        int minAbsValue = Integer.MAX_VALUE;
8      
9        // Count of negative numbers
10        int negativeCount = 0;
11      
12        // Iterate through each row in the matrix
13        for (int[] row : matrix) {
14            // Iterate through each element in the row
15            for (int element : row) {
16                // Count negative numbers
17                if (element < 0) {
18                    negativeCount++;
19                }
20              
21                // Get absolute value of current element
22                int absoluteValue = Math.abs(element);
23              
24                // Update minimum absolute value
25                minAbsValue = Math.min(minAbsValue, absoluteValue);
26              
27                // Add absolute value to total sum
28                totalSum += absoluteValue;
29            }
30        }
31      
32        // If even number of negatives, all can be made positive
33        // If odd number of negatives, one value must remain negative (choose the smallest)
34        if (negativeCount % 2 == 0) {
35            return totalSum;
36        } else {
37            // Subtract twice the minimum value (once to remove it from sum, once for negative)
38            return totalSum - 2 * minAbsValue;
39        }
40    }
41}
42
1class Solution {
2public:
3    long long maxMatrixSum(vector<vector<int>>& matrix) {
4        // Initialize sum of absolute values
5        long long totalSum = 0;
6      
7        // Track the minimum absolute value and count of negative numbers
8        int minAbsValue = INT_MAX;
9        int negativeCount = 0;
10      
11        // Iterate through each row in the matrix
12        for (const auto& row : matrix) {
13            // Process each element in the current row
14            for (int value : row) {
15                // Count negative numbers
16                if (value < 0) {
17                    negativeCount++;
18                }
19              
20                // Get absolute value of current element
21                int absValue = abs(value);
22              
23                // Update minimum absolute value seen so far
24                minAbsValue = min(minAbsValue, absValue);
25              
26                // Add absolute value to total sum
27                totalSum += absValue;
28            }
29        }
30      
31        // If even number of negatives, all can be made positive
32        // If odd number of negatives, one must remain negative (choose the smallest)
33        if (negativeCount % 2 == 0) {
34            return totalSum;
35        } else {
36            // Subtract twice the minimum to account for it being negative instead of positive
37            return totalSum - 2 * minAbsValue;
38        }
39    }
40};
41
1/**
2 * Calculates the maximum sum of a matrix after applying allowed operations.
3 * Operations allow multiplying any adjacent pair of elements by -1.
4 * 
5 * @param matrix - 2D array of integers
6 * @returns The maximum possible sum after any number of operations
7 */
8function maxMatrixSum(matrix: number[][]): number {
9    // Initialize variables:
10    // totalSum: sum of absolute values of all elements
11    // negativeCount: count of negative numbers in the matrix
12    // minAbsValue: smallest absolute value in the matrix
13    let totalSum: number = 0;
14    let negativeCount: number = 0;
15    let minAbsValue: number = Infinity;
16  
17    // Iterate through each row in the matrix
18    for (const row of matrix) {
19        // Process each element in the current row
20        for (const element of row) {
21            // Count negative numbers
22            if (element < 0) {
23                negativeCount++;
24            }
25          
26            // Calculate absolute value of current element
27            const absoluteValue: number = Math.abs(element);
28          
29            // Add absolute value to total sum
30            totalSum += absoluteValue;
31          
32            // Track the minimum absolute value
33            minAbsValue = Math.min(minAbsValue, absoluteValue);
34        }
35    }
36  
37    // If even number of negatives, all can be eliminated
38    // If odd number of negatives, one must remain - choose the smallest
39    return negativeCount % 2 === 0 ? totalSum : totalSum - 2 * minAbsValue;
40}
41

Time and Space Complexity

The time complexity is O(m Γ— n), where m is the number of rows and n is the number of columns of the matrix. This is because the algorithm uses nested loops to iterate through every element in the matrix exactly once - the outer loop iterates through each row, and the inner loop iterates through each element in that row.

The space complexity is O(1). The algorithm only uses a constant amount of extra space regardless of the input size. The variables mi, s, and cnt are single values that don't scale with the size of the input matrix. No additional data structures are created that depend on the matrix dimensions.

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Misunderstanding the Operation's Constraint

Pitfall: A common mistake is thinking you can flip the sign of any single element independently. The operation MUST flip exactly two adjacent elements simultaneously. This constraint is crucial because it means:

  • You cannot change just one element's sign in isolation
  • The total number of negative elements changes by either 0 or Β±2 with each operation

Why it matters: If you misunderstand this, you might think you can always make all elements positive, which is incorrect when starting with an odd number of negative elements.

Solution: Remember that each operation affects exactly two elements. This is why parity (odd/even count) of negative numbers is the key insight.

2. Incorrect Calculation When One Element Must Remain Negative

Pitfall: When an odd number of negatives exists, developers often make errors in the final calculation:

# Wrong approaches:
return total_absolute_sum - min_absolute_value  # Only subtracts once
return total_absolute_sum + min_absolute_value  # Adds instead of subtracts

Why it's wrong: When we compute total_absolute_sum, we add the absolute value of ALL elements (including the one that will remain negative). To correct this:

  • We need to remove the positive contribution: -min_absolute_value
  • We need to add the negative contribution: -min_absolute_value
  • Total adjustment: -2 * min_absolute_value

Solution: Always use total_absolute_sum - 2 * min_absolute_value for the odd case.

3. Not Considering Zero Values

Pitfall: Forgetting that zero values can exist in the matrix and not handling them properly when tracking the minimum absolute value.

Why it matters: If the matrix contains zeros and you have an odd number of negative values, you can always choose to "keep" a zero as your "negative" element (since -0 = 0), resulting in no loss to your sum.

Solution: The code correctly handles this because:

  • abs(0) = 0 will become the minimum absolute value
  • When odd negatives exist: total_absolute_sum - 2 * 0 = total_absolute_sum
  • This naturally gives the optimal result

4. Integer Overflow in Large Matrices

Pitfall: For very large matrices with large values, the sum might exceed standard integer limits in some languages.

Solution: In Python, this isn't an issue due to arbitrary precision integers. In other languages like Java or C++, consider using long or long long data types:

long totalSum = 0;  // Use long instead of int

5. Inefficient Minimum Tracking Initialization

Pitfall: Initializing the minimum absolute value incorrectly:

# Wrong: might miss actual minimum if all values are large
min_absolute_value = 0  

# Wrong: might cause issues if matrix is empty
min_absolute_value = matrix[0][0]  

Solution: Initialize with float('inf') to ensure any actual value will be smaller, and the min() function will work correctly on the first comparison.

Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

Which of the following array represent a max heap?


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More