-
Notifications
You must be signed in to change notification settings - Fork 2
feat(arrays, puzzles, matrix): lucky number in a matrix #115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 2 commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,105 @@ | ||
| # Lucky Numbers in a Matrix | ||
|
|
||
| Given an m × n matrix of distinct numbers, return the lucky number in the matrix. | ||
|
|
||
| > A lucky number is an element of the matrix such that it is the smallest element in its row and largest in its column. | ||
|
|
||
| Constraints | ||
|
|
||
| - m = `matrix.length` | ||
| - n = `matrix[i].length` | ||
| - 1 <= m, n <= 50 | ||
| - 1 <= `matrix[i][j]` <= 10^5 | ||
| - All elements in the matrix are distinct. | ||
|
|
||
| ## Examples | ||
|
|
||
|  | ||
|  | ||
|  | ||
|
|
||
| ## Solution | ||
|
|
||
| The core idea behind the solution is to recognize that there can be, at most, one lucky number in the matrix. This is | ||
| proven by contradiction, as having two such numbers would violate the unique conditions for being a lucky number. | ||
|
|
||
| > **Proof by contradiction:** | ||
| > | ||
| > Suppose we have an integer x located at row r1 and column c1 in a matrix. The integer x is the smallest value in its | ||
| > row and the largest value in its column, making it a lucky number. | ||
| > Now, assume another integer y exists in row r2 and column c2. For the sake of argument, let’s assume y is also a | ||
| > lucky number, meaning it is the smallest value in its row and the largest in its column. | ||
| > We assess these assumptions using the following steps: | ||
| > | ||
| > 1. As `y` is a lucky number, the smallest value is in row r2 and the largest value is in column c2. Let’s denote the | ||
| > integer at position (r2,c2) as `a` | ||
| > - Then, `y` < `a` because `y` is the minimum in its row | ||
| > - Then, `x` > `a` because `x` is the maximum in it column. | ||
| > | ||
| > Therefore `y` < `x` | ||
| > | ||
| > 2. Next, let's consider the integer at position (r1, c2), which we'll call `b` | ||
| > - Then, `y` > `b` because `y` is the maximum in its column | ||
| > - Then, `x` < `b` because `x` is the minimum in its row | ||
| > | ||
| > Therefore `y` > `x` | ||
| > | ||
| > This leads to a contradiction, as we deduced `y<x` and `y>x`. This inconsistency implies that our initial assumption— | ||
| > that y is a lucky number—is incorrect. Therefore, only x can be the lucky number in this configuration. | ||
|
|
||
| This problem can be solved using a greedy algorithm that analyzes the matrix row by row and column by column. | ||
|
|
||
| We start by iterating over the rows to find the minimum values. Out of those minimum values, we choose the largest | ||
| minimum value and store it in r_largest_min. Similarly, we calculate the maximum values in columns and after finding | ||
| all the largest values, we choose the smallest of them and store them in c_smallest_max. Once we have found the values | ||
| in both rows and columns, we match them to see if they are the same. If they are, we return either of the values; | ||
| r_largest_min or c_smallest_max. Otherwise if now matching value is found, we return an empty matrix. | ||
|
|
||
| Following are the detailed steps of the algorithm that we have just discussed: | ||
|
|
||
| 1. We define two variables, r_largest_min and c_smallest_max: | ||
|
|
||
| - r_largest_min is set to negative infinity (float('-inf')) to ensure any row’s minimum value can be updated. | ||
| - c_smallest_max is set to positive infinity (float('inf')) to ensure any column’s maximum value can be updated. | ||
|
|
||
| 2. For each row in the matrix: | ||
|
|
||
| - We calculate the minimum value of the row (r_min). | ||
| - Then, we update r_largest_min to the maximum of r_largest_min and r_min. | ||
| - The steps above ensure we consider only minimum values in their rows, narrowing the candidate set for a lucky number. | ||
|
|
||
| 3. For each column in the matrix: | ||
|
|
||
| - We calculate the maximum value of the column (c_max) by iterating over all rows. | ||
| - Next, we update c_max_min to the minimum of c_smallest_max and c_max. | ||
| - The above steps ensure we consider only maximum values in their columns, further narrowing the candidate set for a lucky number. | ||
|
|
||
| 4. Finally, we compare whether r_largest_min equals c_smallest_max. If TRUE, we return the value stored in [r_largest_min]. | ||
| Otherwise, we return an empty array []. The comparison ensures that the identified value satisfies both conditions of | ||
| being the minimum in its row and the maximum in its column, making it a valid lucky number. | ||
|
|
||
|  | ||
|  | ||
|  | ||
|  | ||
|  | ||
|  | ||
|  | ||
|  | ||
|  | ||
|  | ||
|  | ||
|  | ||
|  | ||
|  | ||
|  | ||
|  | ||
|
|
||
| ### Time Complexity | ||
|
|
||
| The time complexity of the solution is O(m×n), where m is the number of columns in the matrix and n is the number of | ||
| rows in the matrix. | ||
|
|
||
| ### Space Complexity | ||
|
|
||
| The solution’s space complexity is O(1) as no extra space is required apart from the few variables. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| from typing import List | ||
|
|
||
|
|
||
| def lucky_numbers(matrix: List[List[int]]) -> List[int]: | ||
| """ | ||
| This function takes a matrix as input and returns a list containing the lucky number(s) if they exist. | ||
|
|
||
| A lucky number is a number that is the maximum of the minimum values from each row and the minimum of the maximum | ||
| values from each column. | ||
|
|
||
| If a lucky number exists, the function returns a list containing that number. Otherwise, it returns an empty list. | ||
|
|
||
| Time Complexity: O(m * n) where m is the number of columns and n is the number of rows in the matrix. | ||
| Space Complexity: O(1) as we are using a constant amount of extra space. | ||
|
|
||
|
BrianLusina marked this conversation as resolved.
|
||
| Args: | ||
| matrix (List[List[int]]): The input matrix. | ||
|
|
||
| Returns: | ||
| List[int]: A list containing the lucky number(s) if they exist, otherwise an empty list. | ||
| """ | ||
| row_length = len(matrix) | ||
| col_length = len(matrix[0]) | ||
|
|
||
| # initialize a variable to keep track of the maximum of the minimum values from each row | ||
| r_largest_min = float("-inf") | ||
|
|
||
| # We start by iterating over the rows to find the minimum values. Out of those minimum values, we choose the | ||
| # largest minimum value and store it in r_largest_min | ||
| for i in range(row_length): | ||
| # find the minimum value in current row | ||
| row_min = min(matrix[i]) | ||
| # update r_largest_min to be the maximum of current r_largest_min and the current row minimum | ||
| r_largest_min = max(r_largest_min, row_min) | ||
|
|
||
| # initialize a variable to keep track of the minimum of the maximum values from each column | ||
| c_smallest_max = float("inf") | ||
| # Similarly, we calculate the maximum values in columns and after finding all the largest values, we choose the | ||
| # smallest of them and store them in c_smallest_max | ||
| for c in range(col_length): | ||
| # find the maximum value in the current row | ||
| col_max = max(matrix[r][c] for r in range(row_length)) | ||
| # update c_smallest_max to be the minium of the current c_smallest_max and the current column maximum | ||
| c_smallest_max = min(c_smallest_max, col_max) | ||
|
|
||
| # If they are, we return either of the values; r_largest_min or c_smallest_max. Otherwise if now matching value is | ||
| # found, we return an empty matrix. | ||
|
|
||
| # check if the maximum of row minima is equal to the minimum of column maxima | ||
| if r_largest_min == c_smallest_max: | ||
| # if they are equal, return a list containing the luky number | ||
| return [r_largest_min] | ||
| # Otherwise, return an empty list indicating no luky number exists | ||
| return [] | ||
Binary file added
BIN
+31.4 KB
...cky_numbers_in_a_matrix/images/examples/lucky_numbers_in_a_matrix_example_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+29.1 KB
...cky_numbers_in_a_matrix/images/examples/lucky_numbers_in_a_matrix_example_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+27.5 KB
...cky_numbers_in_a_matrix/images/examples/lucky_numbers_in_a_matrix_example_3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+20.1 KB
...y_numbers_in_a_matrix/images/solutions/lucky_numbers_in_a_matrix_solution_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+37.2 KB
..._numbers_in_a_matrix/images/solutions/lucky_numbers_in_a_matrix_solution_10.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+38.1 KB
..._numbers_in_a_matrix/images/solutions/lucky_numbers_in_a_matrix_solution_11.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+37.6 KB
..._numbers_in_a_matrix/images/solutions/lucky_numbers_in_a_matrix_solution_12.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+38.6 KB
..._numbers_in_a_matrix/images/solutions/lucky_numbers_in_a_matrix_solution_13.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+38 KB
..._numbers_in_a_matrix/images/solutions/lucky_numbers_in_a_matrix_solution_14.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+45.9 KB
..._numbers_in_a_matrix/images/solutions/lucky_numbers_in_a_matrix_solution_15.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+29.1 KB
..._numbers_in_a_matrix/images/solutions/lucky_numbers_in_a_matrix_solution_16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+27.1 KB
...y_numbers_in_a_matrix/images/solutions/lucky_numbers_in_a_matrix_solution_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+34.5 KB
...y_numbers_in_a_matrix/images/solutions/lucky_numbers_in_a_matrix_solution_3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+34.5 KB
...y_numbers_in_a_matrix/images/solutions/lucky_numbers_in_a_matrix_solution_4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+32.9 KB
...y_numbers_in_a_matrix/images/solutions/lucky_numbers_in_a_matrix_solution_5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+33.9 KB
...y_numbers_in_a_matrix/images/solutions/lucky_numbers_in_a_matrix_solution_6.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+32.4 KB
...y_numbers_in_a_matrix/images/solutions/lucky_numbers_in_a_matrix_solution_7.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+38.1 KB
...y_numbers_in_a_matrix/images/solutions/lucky_numbers_in_a_matrix_solution_8.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+30.2 KB
...y_numbers_in_a_matrix/images/solutions/lucky_numbers_in_a_matrix_solution_9.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 40 additions & 0 deletions
40
puzzles/arrays/lucky_numbers_in_a_matrix/test_lucky_numbers_in_a_matrix.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| import unittest | ||
| from typing import List | ||
| from parameterized import parameterized | ||
| from puzzles.arrays.lucky_numbers_in_a_matrix import lucky_numbers | ||
|
|
||
|
|
||
| class LuckyNumbersInAMatrixTestCase(unittest.TestCase): | ||
|
|
||
| @parameterized.expand( | ||
| [ | ||
| ([[3, 7, 8], [9, 11, 13], [15, 16, 17]], [15]), | ||
| ([[1, 2, 3], [4, 5, 6], [7, 8, 9]], [7]), | ||
| ( | ||
| [ | ||
| [10, 20, 30, 40], | ||
| [5, 25, 35, 50], | ||
| [60, 70, 80, 90], | ||
| [100, 110, 120, 130], | ||
| ], | ||
| [100], | ||
| ), | ||
| ( | ||
| [[12, 18, 23, 50], [5, 16, 25, 45], [4, 15, 26, 48], [3, 14, 27, 60]], | ||
| [12], | ||
| ), | ||
| ([[5]], [5]), | ||
| ([[30, 20, 10], [40, 50, 60], [70, 80, 90]], [70]), | ||
| ([[5, 1, 9], [10, 8, 2], [7, 3, 6]], []), | ||
| ([[22, 11], [88, 77], [55, 44]], [77]), | ||
| ] | ||
| ) | ||
| def test_lucky_numbers_in_matrix( | ||
| self, matrix: List[List[int]], expected: List[int] | ||
| ): | ||
| actual = lucky_numbers(matrix) | ||
| self.assertEqual(expected, actual) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| unittest.main() |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.