Want Help Cracking FAANG?

(Then click this)

×
Back to Question Bank

1380. Lucky Numbers in a Matrix - Leetcode Solution

Code Implementation

class Solution:
    def luckyNumbers (self, matrix):
        min_in_rows = [min(row) for row in matrix]
        max_in_cols = [max(col) for col in zip(*matrix)]
        result = []
        for i in range(len(matrix)):
            for j in range(len(matrix[0])):
                if matrix[i][j] == min_in_rows[i] and matrix[i][j] == max_in_cols[j]:
                    result.append(matrix[i][j])
        return result
      
class Solution {
public:
    vector<int> luckyNumbers (vector<vector<int>>& matrix) {
        vector<int> min_in_rows, max_in_cols;
        for (auto& row : matrix) {
            min_in_rows.push_back(*min_element(row.begin(), row.end()));
        }
        int cols = matrix[0].size();
        for (int j = 0; j < cols; ++j) {
            int col_max = matrix[0][j];
            for (int i = 1; i < matrix.size(); ++i) {
                if (matrix[i][j] > col_max)
                    col_max = matrix[i][j];
            }
            max_in_cols.push_back(col_max);
        }
        vector<int> result;
        for (int i = 0; i < matrix.size(); ++i) {
            for (int j = 0; j < cols; ++j) {
                if (matrix[i][j] == min_in_rows[i] && matrix[i][j] == max_in_cols[j]) {
                    result.push_back(matrix[i][j]);
                }
            }
        }
        return result;
    }
};
      
class Solution {
    public List<Integer> luckyNumbers (int[][] matrix) {
        int rows = matrix.length, cols = matrix[0].length;
        int[] min_in_rows = new int[rows];
        int[] max_in_cols = new int[cols];
        Arrays.fill(min_in_rows, Integer.MAX_VALUE);
        Arrays.fill(max_in_cols, Integer.MIN_VALUE);

        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                min_in_rows[i] = Math.min(min_in_rows[i], matrix[i][j]);
                max_in_cols[j] = Math.max(max_in_cols[j], matrix[i][j]);
            }
        }
        List<Integer> result = new ArrayList<>();
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                if (matrix[i][j] == min_in_rows[i] && matrix[i][j] == max_in_cols[j]) {
                    result.add(matrix[i][j]);
                }
            }
        }
        return result;
    }
}
      
var luckyNumbers  = function(matrix) {
    let min_in_rows = matrix.map(row => Math.min(...row));
    let max_in_cols = [];
    for (let j = 0; j < matrix[0].length; j++) {
        let colMax = matrix[0][j];
        for (let i = 1; i < matrix.length; i++) {
            if (matrix[i][j] > colMax)
                colMax = matrix[i][j];
        }
        max_in_cols.push(colMax);
    }
    let result = [];
    for (let i = 0; i < matrix.length; i++) {
        for (let j = 0; j < matrix[0].length; j++) {
            if (matrix[i][j] === min_in_rows[i] && matrix[i][j] === max_in_cols[j]) {
                result.push(matrix[i][j]);
            }
        }
    }
    return result;
};
      

Problem Description

Given a m x n matrix of distinct integers called matrix, a lucky number is an element of the matrix that is the minimum in its row and the maximum in its column. Return all lucky numbers in the matrix in any order.
  • Each row and column contains only distinct values.
  • There may be zero or more lucky numbers in the matrix.
  • Input: matrix (List of Lists or 2D array)
  • Output: List of all lucky numbers

Thought Process

To solve the problem, let's first understand what a lucky number is: it must be the smallest value in its row, and at the same time, the largest value in its column. The brute-force way would be to check each element in the matrix, and for each, scan its row and column to see if it meets the criteria. However, this approach can be slow, especially for large matrices, since for each element, we might have to check up to O(m + n) elements (where m is the number of rows, n is the number of columns). To optimize, we can precompute the minimum of each row and the maximum of each column. Then, we only need to check which elements are both the row minimum and the column maximum. This reduces unnecessary repeated work.

Solution Approach

The optimized algorithm works as follows:
  1. Find the minimum value in each row:
    • For every row, record its smallest value. This gives us a list of candidates for lucky numbers.
  2. Find the maximum value in each column:
    • For every column, record its largest value. This gives us, for each column, the value(s) that could be a lucky number.
  3. Check for overlap:
    • For each element in the matrix, if it is both the minimum in its row and the maximum in its column, it is a lucky number.

We use arrays/lists to store the row minima and column maxima. By iterating through the matrix and comparing, we efficiently find all lucky numbers.

Example Walkthrough

Let's take the following matrix as an example:

    [
      [3, 7, 8],
      [9, 11, 13],
      [15, 16, 17]
    ]
  
  1. Row minimums:
    • Row 0: min(3, 7, 8) = 3
    • Row 1: min(9, 11, 13) = 9
    • Row 2: min(15, 16, 17) = 15
  2. Column maximums:
    • Col 0: max(3, 9, 15) = 15
    • Col 1: max(7, 11, 16) = 16
    • Col 2: max(8, 13, 17) = 17
  3. Check overlaps:
    • 3: row min, col not max
    • 9: row min, col not max
    • 15: row min, col max → Lucky number!

So the answer is [15].

Time and Space Complexity

  • Brute-force approach:
    • For each element, check its row and column: O(mn(m + n))
  • Optimized approach:
    • Find row minimums: O(mn)
    • Find column maximums: O(mn)
    • Final check for overlaps: O(mn)
    • Total: O(mn)
    • Space: O(m + n) for row and column arrays

Summary

The key insight is that by precomputing the minimum of each row and the maximum of each column, we can efficiently identify all lucky numbers in a single pass through the matrix. This approach reduces repeated work and leverages auxiliary arrays for fast lookups, making the solution both elegant and efficient, with linear time and space complexity relative to the size of the matrix.