在一个行和列都为升序的二维数组中找一个数字

一、问题描述:


          在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样一个二维数组和一个整数,判断数组中是否含有该整数。

          例如:

          二维数组:

          1   2   8    9

          2   4   9    12

          4   7   10  13

          6   8   11  15

          查找数字 7 返回 true, 查找数字 20 返回 false


二、解题思路:


        根据二维数组行和列的升序排列特性,不断缩小查找范围。一种是从右上角向左下角缩小,另一种是从左下角向右下角缩小范围,两种方法思路相似。这里用从右上角缩小范围举例。


       (1)、首先选取数组中右上角的数字,如果该数字等于要查找的数字,查找过程结束

       (2)、如果该数字大于要查找的数字,剔除这个数字所在的列;

       (3)、如果该数字小于要查找的数字,剔除这个数字所在的行。

         也就是说,如果要查找的数字不在数组的右上角,则每一次都在数组的查找范围中剔除一行或者一列,这样每一步都可以缩小查找的范围,直到找到要查找的数字,或者查找范围为空。


         图示举例:在数组中查找数字 7 的缩小查找范围的过程(灰色部分是查找范围)

在一个行和列都为升序的二维数组中找一个数字_第1张图片

好,我们了解了查找过程,实现代码就比较简单了。


三、源代码:


#include 

/*
 *函数功能: 查找指定二维数组中是否含有目标数
 *参数说明: @arr: 二维数组指针
 *          @row: 二维数组的行数
 *			@col: 二维数组的列数
 *			@num: 需要查找的目标数字
 *返回值  : 找到目标数字返回true,找不到返回false
 */
bool Find(int *arr, int row, int col, int num)
{
	bool found = false;

	//判断参数是否有误
	if(arr != NULL && row > 0 && col > 0)
	{
		//定义一个行下标变量和一个列下标变量,每次都指向查找范围的右上角数组元素
		int tempRow = 0;
		int tempCol = col - 1;

		while( tempRow < row && tempCol >= 0 )
		{
			//找到
			if( arr[tempRow * col + tempCol] == num )
			{
				found = true;
				break;
			}
			else if( arr[tempRow * col + tempCol] > num )
			{//排除一列
				tempCol--;
			}
			else if( arr[tempRow * col + tempCol] < num )
			{//排除一行
				tempRow++;
			}
		}
	}
	return found;
}

int main(void)
{
	int arr[4][4] = {{1,2,8,9},{2,4,9,12},{4,7,10,13},{6,8,11,15}};

	for(int i = 0; i<4; i++)
	{
		for(int j = 0; j<4; j++)
			printf("%4d", arr[i][j]);
		printf("\n");
	}

	if(Find((int *)arr, 4, 4, 7) == true)
	{
		printf("找到了\n");
	}
	else
	{
		printf("没找到\n");
	}
	return 0;
}


四、运行截图:


在一个行和列都为升序的二维数组中找一个数字_第2张图片


本博文内容来自剑指Offer!


        

你可能感兴趣的:(剑指Offer)