Skip to content

Commit 03986a7

Browse files
author
Thuy Trinh
committed
Solution for "Search a 2D Matrix II"
1 parent 6e7371a commit 03986a7

File tree

3 files changed

+95
-0
lines changed

3 files changed

+95
-0
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
```
2+
[
3+
[1, 4, 7, 11, 15],
4+
[2, 5, 8, 12, 19],
5+
[3, 6, 9, 16, 22],
6+
[10, 13, 14, 17, 24],
7+
[18, 21, 23, 26, 30]
8+
]
9+
```
10+
11+
* Binary search on `[1, 4, 7, 11, 15]`:
12+
* If we find the target, return true.
13+
* Otherwise, return the index of max element which is smaller than the target. In this case, it's the index of `4`.
14+
* Binary search on `[2, 5, 8, 12, 19]` but the right bound is the index we retrieved from earlier step. That means `[2, 5]`. We find `5`, then return true.
15+
16+
How binary search work?
17+
18+
Ex: `[1, 4, 7, 11, 15]`, target is 5.
19+
20+
middleIndex = (0 + 4) / 2 = 2, middle = 7. 7 > 5, so find on [1,4].
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package leetcode.searchmatrix2
2+
3+
sealed class Result
4+
object Found : Result()
5+
data class NotFoundYet(val maxIndex: Int) : Result()
6+
7+
/**
8+
* https://leetcode.com/problems/search-a-2d-matrix-ii/description/
9+
*/
10+
class Solution {
11+
// a = [7, 8, 11, 15, 15], target = 12
12+
private fun IntArray.bs(
13+
left: Int = 0, // left = 3
14+
right: Int = size - 1, // right = 2
15+
target: Int // target = 12
16+
): Result {
17+
if (left > right) {
18+
return NotFoundYet(right)
19+
}
20+
21+
val middle = (left + right) / 2 // middle = 3
22+
val m = this[middle] // m = 15
23+
return when {
24+
m == target -> Found // false
25+
m < target -> bs(middle + 1, right, target) // false
26+
else -> bs(left, middle - 1, target) // true
27+
}
28+
}
29+
30+
fun searchMatrix(matrix: Array<IntArray>, target: Int): Boolean {
31+
if (matrix.isEmpty() || matrix.first().isEmpty()) {
32+
return false
33+
}
34+
35+
var rightIndex = matrix.first().size - 1
36+
matrix.takeWhile { it.first() <= target }
37+
.forEach {
38+
val r = it.bs(right = rightIndex, target = target)
39+
when (r) {
40+
is Found -> return true
41+
is NotFoundYet -> rightIndex = r.maxIndex
42+
}
43+
}
44+
return false
45+
}
46+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package leetcode.searchmatrix2
2+
3+
import org.amshove.kluent.shouldBeFalse
4+
import org.amshove.kluent.shouldBeTrue
5+
import org.junit.Test
6+
7+
class SolutionTest {
8+
@Test
9+
fun searchMatrix() {
10+
Solution().searchMatrix(arrayOf(
11+
intArrayOf(1, 4, 7, 11, 15),
12+
intArrayOf(2, 5, 8, 12, 19),
13+
intArrayOf(3, 6, 9, 16, 22),
14+
intArrayOf(10, 13, 14, 17, 24),
15+
intArrayOf(18, 21, 23, 26, 30)
16+
), target = 5).shouldBeTrue()
17+
Solution().searchMatrix(arrayOf(
18+
intArrayOf(3, 5, 9, 9, 14),
19+
intArrayOf(7, 8, 11, 15, 15),
20+
intArrayOf(8, 10, 16, 16, 17)
21+
), target = 12).shouldBeFalse()
22+
Solution().searchMatrix(arrayOf(
23+
intArrayOf(1)
24+
), target = 5).shouldBeFalse()
25+
Solution().searchMatrix(arrayOf(
26+
intArrayOf(2, 5, 8, 12, 19)
27+
), target = 19).shouldBeTrue()
28+
}
29+
}

0 commit comments

Comments
 (0)