Skip to content

Commit 7d7f276

Browse files
author
Albert Hu
authored
Merge pull request #13 from alberthu16/day18
Day 18: search matrix pt2 in ruby!!
2 parents 872fbc7 + 95bf80f commit 7d7f276

File tree

2 files changed

+129
-0
lines changed

2 files changed

+129
-0
lines changed

day18/README.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
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+

day18/searchMatrix2.rb

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
def searchMatrix(matrix, target)
2+
# the downside to this is that I do a binary search
3+
# on every row before I return
4+
matrix.map {|row| binarySearch(row, target)}.any? {|result| result == true}
5+
end
6+
7+
###########
8+
# Helpers #
9+
###########
10+
11+
def binarySearch(row, target)
12+
low, high = 0, row.size
13+
14+
while low < high
15+
mid = (low + high) / 2
16+
if row[mid] == target
17+
return true
18+
elsif target > row[mid]
19+
low = mid + 1
20+
else
21+
high = mid
22+
end
23+
end
24+
25+
false
26+
end
27+
28+
#########
29+
# Tests #
30+
#########
31+
32+
class AssertionError < RuntimeError
33+
end
34+
35+
def assert &block
36+
raise AssertionError unless yield
37+
end
38+
39+
def tests
40+
matrix = [[1,2,3],
41+
[4,5,6],
42+
[7,8,9]]
43+
assert { searchMatrix(matrix, 1) }
44+
assert { searchMatrix(matrix, 2) }
45+
assert { searchMatrix(matrix, 5) }
46+
assert { searchMatrix(matrix, 6) }
47+
assert { searchMatrix(matrix, 8) }
48+
assert { searchMatrix(matrix, 9) }
49+
50+
assert { searchMatrix([[]], 0) == false }
51+
assert { searchMatrix([[0]], 1) == false }
52+
assert { searchMatrix([[1, 2]], 0) == false }
53+
assert { searchMatrix([[1],[2],[3]], 0) == false }
54+
assert { searchMatrix([[1],[2],[3]], 1) == true }
55+
assert { searchMatrix([[1],[2],[3]], 3) == true }
56+
end
57+
58+
tests()

0 commit comments

Comments
 (0)