更多2019年的技术文章,欢迎关注我的微信公众号:码不停蹄的小鼠松(微信号:busy_squirrel),也可扫下方二维码关注获取最新文章哦~
T:
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
Constraints:
时间限制:1秒空间限制:32768K
My Solution:
由于各行和各列都遵循一次增大的规则,给定一个数target,首先在这样一个二维数组中找到其右边界rightSide和下边界downSide,如果二维数组中有数值和target相等,那只能在这个边界的范围内,出了边界就都是比target大的数值了。
在第一行往右,找第一个大于target的数值作为该右边界;
在第一列往下,找第一个大于target的数值作为该下边界。
遍历:
整体上,采用的从右边向左,从上往下的方式进行,在一个死循环当中进行,如果找到相等值,break循环,返回true,或者越界,那就break循环,返回false。
因为第一行的右边界,是第一个比target大的数值,记为 A 0 , j A_{0,j} A0,j,也就是说其左边的一个数值 A 0 , j − 1 A_{0, j-1} A0,j−1,是比target小的,这样,直接下移一格到 A 1 , j A_{1, j} A1,j,该数值是比target大的,然后依次往左走,找到第一个比target小的,如果相等,就退出,返回true,否则就再下移一格,继续进行比较。
代码如下:
public class Solution {
public boolean Find(int [][] array,int target) {
boolean flag = false;
//先在二维数组中找到右边界和下边界
int rightSide = array[0].length;
int downSide = array.length;
// 判断该二维数组是否为空数组
if (rightSide ==0 && downSide == 1) {
return flag;
}
// 右边界
for (int j = 0; j < array[0].length; j++) {
if (array[0][j] == target) {
flag = true;
return flag;
} else if (array[0][j] > target) {
rightSide = j;
break;
}
}
// 下边界
for (int i = 0; i < array.length; i++) {
if (array[i][0] == target) {
flag = true;
return flag;
}else if (array[i][0] > target) {
downSide = i;
break;
}
}
// 看是否第一个值就比target大
if (rightSide == 0 && downSide == 0) {
return flag;
}
// 第一行和第一列都是不可能有相等值的,否则在前面的步骤就已经返回
// 自右向左,自上向下搜索
int i = 0;
int tempi = 0;
int j = 0;
while (true) {
for (j = rightSide-1; j > -1 && array[tempi][j] > target; j--);
if (j == -1) {
break;
}
if (array[tempi][j] == target ) {
flag = true;
break;
}
rightSide = j; // 重新定义右界限
for (i = tempi; i < downSide && array[i][rightSide] < target; i++);
if (i == downSide) {
break;
}
if (array[i][rightSide] == target) {
flag = true;
return flag;
}
tempi = i;
}
return flag;
}
}
别人的思路:
“觉者”发表于 2015-08-26 14:14:12:
思路:首先我们选择从左下角开始搜寻,(为什么不从左上角开始搜寻,左上角向右和向下都是递增,那么对于一个点,对于向右和向下会产生一个岔路;如果我们选择从左下脚开始搜寻的话,如果大于就向右,如果小于就向下)。
public class Solution {
public boolean Find(int [][] array,int target) {
int len = array.length-1;
int i = 0;
while((len >= 0)&& (i < array[0].length)){
if(array[len][i] > target){
len--;
}else if(array[len][i] < target){
i++;
}else{
return true;
}
}
return false;
}
}
改进:
我的出发点与之类似,只是判断的条件多了些,其实用他的思路,也适用我的情况。
这是我的改进代码:
public boolean Find(int [][] array, int target) {
boolean flag = false;
int rowLen = array.length;
int colLen = array[0].length;
int j = colLen -1;
int i = 0;
while (i < rowLen && j > -1) {
if (array[i][j] > target) {
j --;
} else if (array[i][j] < target) {
i ++;
} else {
flag = true;
return flag;
}
}
return flag;
}
在这个代码里面,就不需要考虑该二维数组是否为空的情况,但是在我的第一版代码中,由于需要界定边界,需要考虑二维数组是否为空的情况。
判断是否为空,这一情况很多人都会忽略掉,这是大家的惯性思维使然,思考问题的不全面导致。
更多2019年的技术文章,欢迎关注我的微信公众号:码不停蹄的小鼠松(微信号:busy_squirrel),也可扫下方二维码关注获取最新文章哦~