持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情
题目
在一个二维数组中,每行都在按照从左到右递增顺序排序,每一列都按照从上往下递增顺序排序。输入一个该二维数组和整数,判断数组中是否有该整数。
比如一个二维数组:
[ [1],[2],[8],[9]
[2],[4],[9],[12]
[4],[7],[10],[13]
[6],[8],[11],[15]
]
然后在表格中查找数字7,返回值是true;查找数字5,返回值则是false。
解题思路
暴力解法
直接循环二维数组从二维数组中遍历每个元素查找出输入值是否存在。
for (int[] row : matrix) { // 二维中的一维数组
for (int element : row) { // 一维数组遍历
if (element == target) {
return true;
}
}
}
return false;
行列剔除法
二维数组从左到右和从上到下都是递增排序因此可以依据这一特性实现更巧妙的查找法。
举例说明:
- 查找数是7的时候,二维数组第一行最后一个数字是9。
- 可以推断出7肯定不在9所在的列。
- 因此可以只推断前3列中是否存在7。
- 9的前一个数字是8,同理也剔除了8所在列的可能性。
- 8的前一个数字是2,7只有可能出现在2的下面。
| 在9后面才是7查找范围 | 在8后面是7查找范围 | 2小于7,下方是7查找范围 | 同2情况,4下方是7查找范围 |
整体查找思路:
- 起始从数组右上角开始查找。
- 数字大于查找对象,剔除该列。
- 数字小于查找对象,剔除该行。
- 每次查找若未找到查找对象,剔除列或者行直到范围为空或查找到对象。
int m = matrix.length, n = matrix[0].length;
int x = 0, y = n - 1;// 起始位置数组右上角开始
while (x < m && y >= 0) {
if (matrix[x][y] == target) { //
return true;
}
if (matrix[x][y] > target) {
--y; //大于 减去列
} else {
++x; //小于 加行
}
}
return false;
总结
本题主要思路是从规则中找逻辑再制定查找方法实现高效解题方案。如果本题二维数组无特定规则(递增属性),查找方案就不能再使用行列剔除的方案只能采用暴力解法去找遍历查询,此外全量遍历也能采用二分法这种比普通遍历高效一些的方式实现。因此充分理解题意利用规则逻辑找规律和方法尤为重要,从中或许就能找到思路和解题方法。