题目描述
在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
示例
示例1:
现有矩阵 matrix 如下:
[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]
给定 target = 5,返回 true。
给定 target = 20,返回 false。
限制:
0 <= n <= 1000
0 <= m <= 1000
题目分析
根据题目可知:
- 这是一个二维数组
- 每一行的数组都是升序的
- 每一列从上到下递增
解题思路
思路一:两重循环
这个都知道就不说了
思路二:数组扁平化
题目给的是个二维数组,那么我们是不是可以将二维数组变成一个一维数组呢,变成一维数组是不是就方便多了,直接一重循环搞定。
那么怎么让二维变成一维呢?这就需要知道数组扁平化了。实现数组扁平化的方式有很多种,比如数组自带的 flat()等等;
如果对数组扁平化有兴趣的,可以去看看 神三元大佬 写的 JS数组扁平化(flat)方法总结,里面有很多种实现数组扁平化的方法。
思路三: 双指针
没错哈,又又又是双指针。可能有人会好奇这怎么用双指针啊,其实仔细想想就知道了。
我们可以把数组每一行当做左指针,把每一行数组中的元素下标作为右指针。
- 首先左指针当然是从 0 开始,右指针(也可从 0 开始)可从每一行数组最后的元素开始;
- 左右指针有了之后,接下来就开始循环了;
- 当左指针小于二维数组的长度且右指针大于等于 0 的时候,如果当前元素 == target,就返回true;如果当前元素 < target ,说明这一行数组中最大的值都比target小,那么就直接跳过该行,在下一行中找;如果当前数组的第一个值都比target大,说明该行的数组都比 target 大,并且后面的所有数组都比target大,所以直接跳出循环;
可能这样说的话不是那么的直观,那就看下面的代码。
AC代码
思路一: 两重循环
var findNumberIn2DArray = function(matrix, target) {
for(let i = 0; i < matrix.length; i++) {
let arr = matrix[i]
for(let j = 0; j < arr.length; j++) {
// if(arr[arr.length - 1] < target || arr[j] > target)
// break
if(arr[j] == target) {
return true
}
}
}
return false
}
思路二:数组扁平化
- 利用数组自带的方法
var findNumberIn2DArray = function(matrix, target) {
return matrix.flat(Infinity).includes(target)
}
- 利用some实现数组扁平化
var findNumberIn2DArray = function(matrix, target) {
let arr = flatten(matrix)
if(arr.some(item => item == target)) {
return true
}
return false
}
function flatten(matrix) {
while(matrix.some((item) => Array.isArray(item))) {
matrix = [].concat(...matrix)
}
return matrix
}
思路三: 双指针
var findNumberIn2DArray = function(matrix, target) {
if(matrix.length < 1 || matrix[0].length < 1) return false
let row = 0;
let col = matrix[row].length - 1
while(row < matrix.length && col >= 0) {
if(matrix[row][col] == target) {
return true
} else if(matrix[row][col] < target) {
// 如果当前数组最大的都比target小
// 就直接遍历下一行数组
row++
} else if(matrix[row][0] > target){
// 如果当前数组第一个值都比target大,
// 后面所有的数组都比target大,所以直接结束循环
break
} else {
col--
}
}
return false
};
总结
好难受啊,那种想说又说不出来的感觉。。。如果感兴趣的话,不妨去看看我其他文章,感觉还是有点意思的。
继续努力,hxdm!!!
本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情