Leetcode 74 Search a 2D Matrix

search a 2d matrix
这道题乍一看很简单,其实还是有很多细节值得注意的。
首先说明,如果题目中是按照C语言的格式给出的matrix,也就是给出int m[][],再给出row和column,那么实际上我们可以将其作为一维数组 int m[row*column],来直接使用二分查找。复杂度是O(log(row*column))


从high level讲,程序的思路大致是这样:首先通过二分查找找到对应的row,再二分查找找到对应的column,所以复杂度应该是O(log(row)+log(column))= O(log(row*column))。所以实际上,这两种方式复杂度一样。


查找相应row的时候,我们的标准是:如果当前行(mid指向的行)最大的元素都比target要小,那么left = mid+1。如果当前行最小的元素都比target大,那么right = mid-1。如果target在当前行第一个和最后一个元素中间,那么我们认为找到这一行了。
其实这里是没有例外的。仔细想想看,当前行第一个元素和最后一个元素将整个实数分为了三个区域,那么target一定是位于这三个区域之中的,对不对?
有一种情况我们需要观察一下:那就是target比当前行(如第2行)第一个元素要小,比上一行(如第1行)最后一个元素要大。这种情况下,我们实际上不是在第2行进行处理的,而是通过right = mid-1转到第1行处理。而到第1行之后,由于target比第1行最后一个元素大,那么left = mid+1,将会造成left>right,从而跳出循环。


至于找到指定行之后如何找相应元素,就和普通的二分查找一样,这里不再赘述。


编程中需要注意的几个细节:
首先是二分法。使用二分的时候一定要注意,第一,循环中止的条件是left<=right,不然有可能忽略情况;第二,每次二分完毕之后,left=mid+1,而不是left=mid,注意体会。因为如果mid指向的元素不可能的话,我们下一次查找的时候应该从mid+1开始!
第二是关于矩阵操作。凡是给出矩阵的,第一不要定义xy,而一律用row和column来代替。原因很简单,xy和row/column完全是反着的,还要换算,非常麻烦。同时,如果用vector给出元素,坐标的极限记得要减去1!





class Solution
{
public:
    bool searchMatrix(vector<vector<int> > &m, int target)
	{
		if (m.size() == 0)
			return false;
		int row = m.size() - 1;
		int column = m[0].size() - 1;
		int left = 0, right = row, mid = left + (right - left) / 2;
		int rowFound = -1;
		//!!!注意什么时候小于,什么时候小于等于
		while (left <= right)
		{
			mid = left + (right - left) / 2;
			if (m[mid][0] <= target && m[mid][column] >= target)
			{
				rowFound = mid;
				break;
			}
			else if (m[mid][column] < target)
				left = mid + 1;
			else if (m[mid][0] > target)
				right = mid - 1;
		}
		if (rowFound < 0)
			return false;
		//find the element in the corresponding row
		left = 0;
		right = column;
		while (left <= right)
		{
			mid = left + (right - left) / 2;
			if (m[rowFound][mid] == target)
				return true;
			else if (m[rowFound][mid] < target)
				left = mid + 1;
			else
				right = mid - 1;
		}
		return false;
	}
};



NOTE: Although the following code work, but it has a few bugs and is not very efficient

class Solution
{
public:
    bool searchMatrix(vector<vector<int> > &m, int target)
	{
		if(m.size() == 0)
			return false;
		int row = m.size()-1;
		int column = m[0].size()-1;
		int left = 0, right = row, mid = left + (right - left) / 2;
		bool rowFound = false;
		//!!!注意什么时候小于,什么时候小于等于
		while (left <= right)
		{
			mid = left + (right - left) / 2;
			if (m[mid][0] <= target && m[mid][column] >= target)
			{
				rowFound = true;
				break;
			}
			else if (m[mid][column] < target)
				left++;
			else if (m[mid][0] > target)
				right--;

		}
		if (!rowFound)
			return false;
		left = 0;
		right = column;
		int currentrow = mid;
		while (left <= right)
		{
			mid = left + (right - left) / 2;
			if (m[currentrow][mid] == target)
				return true;
			else if (m[currentrow][mid] < target)
				left++;
			else
				right--;
		}
		return false;

	}
};


你可能感兴趣的:(Leetcode 74 Search a 2D Matrix)