在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。
请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
样例
输入数组:
[ [1,2,8,9], [2,4,9,12], [4,7,10,13], [6,8,11,15] ]
如果输入查找数值为7,则返回true,
如果输入查找数值为5,则返回false。
namespace ConsoleApp2;
public class 二维数组中的查找
{
//思路1:暴力解法
//时间O(mn)
//空间O(1)
public static bool FindNumberIn2DArray(int[][] matrix, int target)
{
if (matrix.Length>=1 && matrix[0].Length>=1)
{
for (int col = 0; col < matrix.Length; col++)
{
for (int row = 0; row < matrix[0].Length; row++)
{
if (matrix[col][row] == target)
{
return true;
}
}
}
}
return false;
}
/*
* 1,2,3,4
* 2,3,4,5
* 3,4,5,6
*/
//思路2:这个题有个特点就是,从右往右,从上往下,是依次递增的,这时候一定要利用想象力
//刚开始,一直想着是左上往右下的对角线,然后发现有问题,
//因为对角线是他的x轴和y轴的最大的,这样利用查找就需要两边都查找
//后来发现从右上角往左下的对角线,可以完美的解决这个问题,
//因为这个对角线上的是处于最中间的值,他的左边都小于他,下面都大于他,这样就可以直接排除了大部分,
//剩下的有两种选择:
//注意:此刻可能想可以利用二分查找,直接查找他的下面或者左边的,这样不对,因为目标数不一定他所在的行列上,例如下面的你想要找7,7并不在4的右上角
/*
* 1,2,3,4
* 2,3,4,5
* 3,4,7,9
*/
//这种方式只是确定的是范围,7>4只是确定了,7不可能在4的左边,就是第一行出现,这可能是从第二行开始,那么缩小范围,就是只剩下了
//* 2,3,4,5
//* 3,4,7,9
//继续这样循环,不断地缩小范围,直到找到,或者任一一方为0,未找到
//时间O(n+m),一层的循环,m+n
//空间O(1)
public static bool FindNumberIn2DArray2(int[][] matrix, int target)
{
if (matrix.Length>=1 && matrix[0].Length>=1)
{
int cur_col = matrix.Length - 1;
int cur_row = 0;
while (cur_col>=0 && cur_row<=matrix[0].Length - 1)
{
if (matrix[cur_col][cur_row]>target)
{
cur_col -= 1;
}
else if (matrix[cur_col][cur_row]<target)
{
cur_row += 1;
}
else
{
return true;
}
}
}
return false;
}
static void Main(string[] args)
{
//C#中int[][]与int[,]的比较 https://blog.csdn.net/ZUFE_ZXh/article/details/105357772
//int[][]形式的,不应该叫做二维数字,只不过一维数组里包了一维数组,就是在套娃,只有int[,]才是二维数组,int[][]原理上还是一维的。
//int[,] 用arr1.GetLength(0); arr1.GetLength(1);int[][]我们直接获取其Length属性就可以了
int[][] temp_array = new int[][]
{
new int[]{1, 4, 7, 11, 15},
new int[]{2, 5, 8, 12, 19},
new int[]{3, 6, 9, 16, 22},
new int[]{10, 13, 14, 17, 24},
new int[]{18, 21, 23, 26, 30},
};
// int[][] temp_array = new int[][]
// {
// new int[]{-5}
// };
bool num = FindNumberIn2DArray2(temp_array,25);
Console.WriteLine(num);
}
}