力扣-240-搜索二维矩阵

感觉是二维矩阵的DFS或是BFS
很久没做过这方面的题了

有右和下两个方向都可能比当前元素大,我的第一想法是每个节点递归地去判断右节点和下节点,但是这样怎么处理重叠的问题

我觉得可以先按照对角线找,然后再向右、下两个方向找

对角线查其实挺麻烦的,题解中的思路大概是从最后一行/最后一列的第一个元素向下查

先确定元素在某一行/列,然后用二分查找

bool searchMatrix(vector<vector<int>>& matrix, int target) {
	int m = matrix.size(), n = matrix[0].size();
	int i = 0,j=n-1;
	// 先确定目标在某一行/列
	// 跟最大一行/列最小的比,如果小于则递减一行
	while (matrix[i][j]>target)
	{
		if (j==0) return false;
		j--;
	}
	// 用二分查找找
	int left = 0, right = m - 1;
	while (left <= right) {
		int mid = (right + left) / 2;
		if (matrix[mid][j] == target) return true;
		else if (matrix[mid][j] < target) left = mid + 1;
		else right = mid - 1;
	}
	return false;
}

这是我一开始写的代码,我的想法是每次递减一列,找到所在列,然后用二分查找
但是这样是有问题的,如果只对行或者只对列做处理,其实会有 最大值>target>最小值的多个行满足条件的情况
比如
1,2,3,4,5 6,7,8,9,10 11,12,13,14,15 16,17,18,19,20 21,22,23,24,25
在这里找19的话,每一列都满足条件

然后去瞄题解,应该动态地去缩小一个矩形,每次减一行或者一列

因为右上角的数字是一行最大又是一列最小

  • 如果它>target,即一列最小的数字都>target,target一定不在这一列,缩小一列
  • 同理<就缩小一行

这种行列的交叉点可以判断到任何一个元素,后面意识到这么做的话根本不需要二分查找

同理也可以从左下角开始查找

bool searchMatrix(vector<vector<int>>& matrix, int target) {

	int m = matrix.size(), n = matrix[0].size();
	int i = 0, j = n - 1;

	while (i<m||j>=0)
	{
		if (matrix[i][j] == target) return true;
		// 列最小的元素比target大,递上一列
		else if (matrix[i][j] > target) j--;
		// 行最大的元素比target小,下一行
		else i++;
	}
	return false;
}

代码非常简洁高效

posted @ 2022-11-05 09:59  YaosGHC  阅读(27)  评论(0)    收藏  举报