Skip to content

Commit 1c1ce51

Browse files
committed
240
1 parent 121d4a6 commit 1c1ce51

File tree

1 file changed

+90
-1
lines changed

1 file changed

+90
-1
lines changed

leetcode-240-Search-a-2D-MatrixII.md

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,95 @@ public boolean searchMatrix(int[][] matrix, int target) {
135135

136136
时间复杂度就是每个节点最多遍历一遍了,`O(m + n)`
137137

138+
# 解法三
139+
140+
参考 [这里](https://leetcode.com/problems/search-a-2d-matrix-ii/discuss/66147/*Java*-an-easy-to-understand-divide-and-conquer-method) ,还有一种解法。
141+
142+
我的理解的话,算是一种变形的二分法。
143+
144+
二分法的思想就是,目标值和中点值进行比较,然后可以丢弃一半的元素。
145+
146+
这道题的话是矩阵,如果我们找到矩阵的中心,然后和目标值比较看能不能丢弃一些元素。
147+
148+
```java
149+
如下图,中心位置是 9
150+
[1, 4, 7, 11, 15],
151+
[2, 5, 8, 12, 19],
152+
[3, 6, /9/,16, 22],
153+
[10, 13, 14, 17, 24],
154+
[18, 21, 23, 26, 30]
155+
156+
通过中心位置, 我们可以把原矩形分成四个矩形, 左上, 右上, 左下, 右下
157+
[1, 4, 7 [11, 15
158+
2, 5, 8 12, 19
159+
3, 6, /9/] 16, 22]
160+
161+
[10, 13, 14 [17, 24
162+
[18, 21, 23] 26, 30]
163+
164+
如果 target = 10,
165+
此时中心值小于目标值,左上角矩形中所有的数都小于目标值,我们可以丢弃左上角的矩形,继续从剩下三个矩形中寻找
166+
167+
如果 target = 5,
168+
此时中心值大于目标值,右下角矩形中所有的数都大于目标值,那么我们可以丢弃右下角的矩形,继续从剩下三个矩形中寻找
169+
```
170+
171+
我们找到了丢弃元素的原则,可以写代码了。
172+
173+
这里的话,矩形我们用左上角和右下角坐标的形式表示,下图是分割后矩形的坐标情况。
174+
175+
![](https://windliang.oss-cn-beijing.aliyuncs.com/240_2.jpg)
176+
177+
我们可以用递归的形式去写,递归出口的话,当矩阵中只有一个元素,直接判断当前元素是不是目标值即可。
178+
179+
还有就是分割的时候可能越界,比如原矩阵只有一行,左下角和右下角的矩阵其实是不存在的,按照上边的坐标公式计算出来后,我们要判断一下是否越界。
180+
181+
```java
182+
public boolean searchMatrix(int[][] matrix, int target) {
183+
if (matrix.length == 0 || matrix[0].length == 0) {
184+
return false;
185+
}
186+
return searchMatrixHelper(matrix, 0, 0, matrix[0].length - 1, matrix.length - 1, matrix[0].length - 1, matrix.length - 1, target);
187+
}
188+
189+
private boolean searchMatrixHelper(int[][] matrix, int x1, int y1, int x2, int y2, int xMax, int yMax, int target) {
190+
//只需要判断左上角坐标即可
191+
if (x1 > xMax || y1 > yMax) {
192+
return false;
193+
}
194+
195+
//x 轴代表的是列,y 轴代表的是行
196+
if(x1 == x2 && y1 == y2){
197+
return matrix[y1][x1] == target;
198+
}
199+
int m1 = (x1 + x2) >>> 1;
200+
int m2 = (y1 + y2) >>> 1;
201+
if (matrix[m2][m1] == target) {
202+
return true;
203+
}
204+
if (matrix[m2][m1] < target) {
205+
// 右上矩阵
206+
return searchMatrixHelper(matrix, m1 + 1, y1, x2, m2, x2, y2, target) ||
207+
// 左下矩阵
208+
searchMatrixHelper(matrix, x1, m2 + 1, m1, y2, x2, y2, target) ||
209+
// 右下矩阵
210+
searchMatrixHelper(matrix, m1 + 1, m2 + 1, x2, y2, x2, y2, target);
211+
212+
} else {
213+
// 右上矩阵
214+
return searchMatrixHelper(matrix, m1 + 1, y1, x2, m2, x2, y2, target) ||
215+
// 左下矩阵
216+
searchMatrixHelper(matrix, x1, m2 + 1, m1, y2, x2, y2, target) ||
217+
// 左上矩阵
218+
searchMatrixHelper(matrix, x1, y1, m1, m2, x2, y2, target);
219+
}
220+
}
221+
```
222+
138223
#
139224

140-
看到有序数组第一反应就是二分了,也就是解法一。解法二的话,从右上角开始遍历的想法很妙。
225+
看到有序数组第一反应就是二分了,也就是解法一。
226+
227+
解法二的话,从右上角开始遍历的想法很妙。
228+
229+
解法三的话思想很简单,就是变形的二分法,每次抛弃一部分元素,但代码的话其实写出来不是很容易,相对于解法一和解法二来说是有些复杂度的。

0 commit comments

Comments
 (0)