Lucky Numbers in a Matrix

Updated on 06 June, 2025
Lucky Numbers in a Matrix header image

Problem Statement

In the given problem, we need to find and return all "lucky numbers" from an m x n matrix of distinct integers. A "lucky number" within the matrix is defined by the specific condition of being the smallest number in its respective row and simultaneously the largest number in its respective column. The task is to identify all such numbers in the matrix and return them in any order.

Examples

Example 1

Input:

matrix = [[3,7,8],[9,11,13],[15,16,17]]

Output:

[15]

Explanation:

15 is the only lucky number since it is the minimum in its row and the maximum in its column.

Example 2

Input:

matrix = [[1,10,4,2],[9,3,8,7],[15,16,17,12]]

Output:

[12]

Explanation:

12 is the only lucky number since it is the minimum in its row and the maximum in its column.

Example 3

Input:

matrix = [[7,8],[1,2]]

Output:

[7]

Explanation:

7 is the only lucky number since it is the minimum in its row and the maximum in its column.

Constraints

  • m == mat.length
  • n == mat[i].length
  • 1 <= n, m <= 50
  • 1 <= matrix[i][j] <= 105.
  • All elements in the matrix are distinct.

Approach and Intuition

  1. Identify the minimum of each row.

    • Iterate through each row and find the minimum element.
    • Keep track of the index position where this minimum element occurs since this will be used to check the column conditions later.
  2. Check if these minimums are the maximum in their respective columns.

    • For each minimum element identified in step 1, check its respective column to verify it's the largest value in that column.
  3. Collect and return all such numbers that satisfy both conditions.

    • An array or list can be used to collect all the values which meet the criteria across the matrix.
    • If no such number is found, return an empty list.

The challenges to handle in this approach include efficiently searching each column multiple times and making sure that the operations stay within reasonable time limits, given the constraints. This method leverages the properties of numbers being distinct which simplifies the checking for maximum or minimum without having to consider ties. Each number’s unique property allows straightforward comparisons without additional checks for duplicate values.

Solutions

  • C++
  • Java
  • Python
cpp
class Solution {
public:
    vector<int> findLuckyNumbers (vector<vector<int>>& grid) {
        int rows = grid.size(), cols = grid[0].size();
        
        int minMaxRowVal = INT_MIN;
        for (int row = 0; row < rows; row++) {

            int minRow = INT_MAX;
            for (int col = 0; col < cols; col++) {
                minRow = min(minRow, grid[row][col]);
            }
            minMaxRowVal = max(minMaxRowVal, minRow);
        }
        
        int maxMinColVal = INT_MAX;
        for (int col = 0; col < cols; col++) {

            int maxCol = INT_MIN;
            for (int row = 0; row < rows; row++) {
                maxCol = max(maxCol, grid[row][col]);
            }
            maxMinColVal = min(maxMinColVal, maxCol);
        }
        
        if (minMaxRowVal == maxMinColVal) {
            return {minMaxRowVal};
        }
        
        return {};
    }
};

The C++ solution provided identifies the lucky numbers in a matrix. Lucky numbers in this context are defined as the minimum values in their rows and the maximum values in their columns. The approach includes the following steps:

  1. Define a class Solution with a public function findLuckyNumbers which accepts a reference to a vector<vector<int>> representing the matrix.

  2. Initialize variables to track the number of rows and columns in the matrix.

  3. Use two nested loops to find the maximum of the minimum values in each row:

    • Initialize minMaxRowVal to the smallest integer possible (INT_MIN) to store the maximum value among the row minimums.
    • For each row, find the minimum value minRow, and then update minMaxRowVal with the maximum of minMaxRowVal and minRow.
  4. Use another set of nested loops to find the minimum of the maximum values in each column:

    • Initialize maxMinColVal to the largest integer possible (INT_MAX) to store the minimum value among the column maximums.
    • For each column, find the maximum value maxCol, and then update maxMinColVal with the minimum of maxMinColVal and maxCol.
  5. Check if minMaxRowVal equals maxMinColVal, which would make it a lucky number. If they are equal, return a vector containing minMaxRowVal.

  6. If no lucky number is found, return an empty vector.

This solution efficiently identifies lucky numbers by separately examining rows and columns, ensuring optimal comparison within each dimension of the matrix.

java
class Solution {
    public List<Integer> findLuckyNumbers(int[][] inputMatrix) {
        int rows = inputMatrix.length, cols = inputMatrix[0].length;

        int maxRowMin = Integer.MIN_VALUE;
        for (int row = 0; row < rows; row++) {
            int currentRowMin = Integer.MAX_VALUE;
            for (int col = 0; col < cols; col++) {
                currentRowMin = Math.min(currentRowMin, inputMatrix[row][col]);
            }
            maxRowMin = Math.max(maxRowMin, currentRowMin);
        }

        int minColMax = Integer.MAX_VALUE;
        for (int col = 0; col < cols; col++) {
            int currentColMax = Integer.MIN_VALUE;
            for (int row = 0; row < rows; row++) {
                currentColMax = Math.max(currentColMax, inputMatrix[row][col]);
            }
            minColMax = Math.min(minColMax, currentColMax);
        }

        if (maxRowMin == minColMax) {
            return new ArrayList<>(Arrays.asList(maxRowMin));
        }

        return new ArrayList<>();
    }
}

The given Java code presents a solution for identifying "lucky numbers" in a matrix. A "lucky number" is defined as a number that is the minimum in its row but maximum in its column. Here's how the code accomplishes this task:

  • First, compute the maximum of all the row minimums in the matrix. This involves iterating through each row, identifying the smallest value in that row, and then tracking the largest of these minimum values.
  • Subsequently, compute the minimum of all the column maximums. This requires traversing each column to find the largest value, and then determining the smallest among these maximum values.
  • After obtaining these two numbers, check if they are the same. If they are, it indicates that the matrix indeed has a lucky number which equals this common value. Return this value wrapped in a list.
  • If they don't match, return an empty list as it indicates there are no lucky numbers.

This solution involves systematic scanning of rows and columns separately to yield potential lucky numbers, ensuring the method efficiently checks each criterion for luckiness with optimal matrix traversal. The result is either a list containing the lucky number or an empty list indicating the absence of a lucky number.

python
class Solution:
    def findLuckiestNumbers(self, grid: List[List[int]]) -> List[int]:
        rows, cols = len(grid), len(grid[0])

        max_of_row_min = float('-inf')
        for x in range(rows):
            row_min = min(grid[x])
            max_of_row_min = max(max_of_row_min, row_min)

        min_of_col_max = float('inf')
        for y in range(cols):
            col_max = max(grid[row][y] for row in range(rows))
            min_of_col_max = min(min_of_col_max, col_max)

        if max_of_row_min == min_of_col_max:
            return [max_of_row_min]
        else:
            return []

This Python solution defines a function findLuckiestNumbers which determines the lucky numbers in a matrix, based on the "lucky number" condition: a number is considered lucky if it is the minimum in its row and the maximum in its column.

The function first calculates the number of rows and columns in the input grid. It initializes variables to store the maximum of the minimum values of the rows (max_of_row_min) and the minimum of the maximum values of the columns (min_of_col_max).

Perform the following steps to determine the lucky number:

  1. Initializing max_of_row_min to negative infinity, loop through each row to find the minimum of each row, then updating max_of_row_min to hold the maximum of these row minimums.
  2. Initializing min_of_col_max to positive infinity, loop through each column, use a generator to find the maximum of each column, and update min_of_col_max to hold the minimum of these column maximums.
  3. Check if max_of_row_min is equal to min_of_col_max. If true, return this value inside a list as it represents the lucky number.
  4. If no such number exists (i.e., no number is both the maximum in its row and the minimum in its column), return an empty list.

In summary, the solution effectively identifies whether there is a qualifying "lucky" number within the matrix, adhering to the definition provided. The algorithm is efficient, considering each element at most twice, which is optimal for matrix operations of this nature.

Comments

No comments yet.