|
| 1 | +question of the day: https://leetcode.com/problems/search-a-2d-matrix-ii/#/description |
| 2 | + |
| 3 | +Write an efficient algorithm that searches for a value in an `m` x `n` |
| 4 | +matrix. This matrix has the following properties: |
| 5 | + |
| 6 | +Integers in each row are sorted in ascending from left to right. |
| 7 | + |
| 8 | +Integers in each column are sorted in ascending from top to bottom. |
| 9 | + |
| 10 | +For example, |
| 11 | + |
| 12 | +Consider the following matrix: |
| 13 | + |
| 14 | +```ruby |
| 15 | +[ |
| 16 | + [1, 4, 7, 11, 15], |
| 17 | + [2, 5, 8, 12, 19], |
| 18 | + [3, 6, 9, 16, 22], |
| 19 | + [10, 13, 14, 17, 24], |
| 20 | + [18, 21, 23, 26, 30] |
| 21 | +] |
| 22 | +``` |
| 23 | + |
| 24 | +Given *target* = `5`, return `true`. |
| 25 | +Given *target* = `20`, return `false`. |
| 26 | + |
| 27 | +## Ideas |
| 28 | + |
| 29 | +Brute force solution: just iterate through every coordinate in the |
| 30 | +matrix and compare value by value to see if any match. Return `true` |
| 31 | +when a match is found, or `false` if the whole matrix has been searched |
| 32 | +without finding a match. This is an `O(rows*columns)` runtime solution, |
| 33 | +but doesn't take advantage of the existing ordering. |
| 34 | + |
| 35 | +Now, unlike yesterday's problem where in addition to the elements |
| 36 | +in each row being ordered in increasing order, the same property held |
| 37 | +across rows. The matices in this problem are not like that. The |
| 38 | +elements in each column are also increasing order now. This means I can't |
| 39 | +do a binary search across all the elements in the matrix as easily. |
| 40 | + |
| 41 | +Something I can still do right off the bat, is a binary search within |
| 42 | +each row. For example, in the example matrix, if I'm going to look for |
| 43 | +`13`, I can start in the middle of the first row, then search the right half |
| 44 | +(since `7` < `13`), then search the right half again (since `11` < `13`) and |
| 45 | +finally give up on the row once I see `15` is the last option. I'd |
| 46 | +move down to the next row and repeat the binary search. This solution |
| 47 | +is a slight improvement, especially on larger matrices. It'd have a |
| 48 | +`O(rows*log(columns))` runtime. However, I'm still not using the |
| 49 | +increasing-down-columns property to my advantage. |
| 50 | + |
| 51 | +At this moment, I can't think of a better way to solve this problem. |
| 52 | + |
| 53 | +I'll just implement the binary search by rows solution for now. |
| 54 | + |
| 55 | +## Code |
| 56 | + |
| 57 | +[Ruby](./searchMatrix2.rb) |
| 58 | + |
| 59 | +## Follow up |
| 60 | + |
| 61 | +I can optimize this approach even further by checking which dimension |
| 62 | +is longer (rows or columns) and doing binary search along the larger |
| 63 | +valued dimension to maximize efficiency. |
| 64 | + |
| 65 | +I'll update this soluiton once I think of an even more optimal approach. |
| 66 | + |
| 67 | +@apengwin says there's a known `O(m + n)` solution to this problem and |
| 68 | +that I should "Think about using the sorted-ness of the matrix to my |
| 69 | +advantage". |
| 70 | + |
| 71 | + |
0 commit comments