#include<iostream>
#include<vector>
using namespace std;
//方法一:分割左下和右上区域法
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
bool result = false;
if (matrix.size() == 0 || matrix[0].size() == 0) {
return result;
}
int numrows = matrix.size();
int numcols = matrix[0].size();
recursion(matrix, 0, numrows, 0, numcols, result, target);
return result;
}
void recursion(vector<vector<int>>& matrix, int rowIndexBegin, int rowIndexEnd, int colIndexBegin, int colIndexEnd, bool& result, int& target) {
if (target<matrix[rowIndexBegin][colIndexBegin] || target>matrix[rowIndexEnd - 1][colIndexEnd - 1])
return;
if (rowIndexEnd - rowIndexBegin == 1)
{
for (int i = colIndexBegin; i < colIndexEnd; i++) {
if (matrix[rowIndexBegin][i] == target) {
result = true;
return;
}
}
}
if (colIndexEnd - colIndexBegin == 1)
{
for (int i = rowIndexBegin; i < rowIndexEnd; i++) {
if (matrix[i][colIndexBegin] == target) {
result = true;
return;
}
}
}
int i = 0, j = 0;
for (i = rowIndexBegin, j = colIndexBegin; i < rowIndexEnd && j < colIndexEnd; i++, j++)
{
if (matrix[i][j] == target) {
result = true;
return;
}
if (matrix[i][j] > target) {
//左下方块
recursion(matrix, i, rowIndexEnd, colIndexBegin, j, result, target);
//右上方块
if (!result) {
recursion(matrix, rowIndexBegin, i, j, colIndexEnd, result, target);
}
return;
}
}
if (i == rowIndexEnd)
recursion(matrix, rowIndexBegin, i, j, colIndexEnd, result, target);
else {
if (!result)
recursion(matrix, i, rowIndexEnd, colIndexBegin, j, result, target);
}
return;
}
};
//这种方法有点问题,出现了TLE问题,本题是从最小元素开始,网友答案从最大元素开始,能通过,并且击败全球99%的运行时间,搞不懂(两种方法思路完全一样)
//方法二:DFS方法(从二维矩阵起点出发,方向只有向左和向下两个方向),按照深度优先收索进行遍历,该方法比暴力求解法好在不会出现n*n的极端情况时间复杂度
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
bool result = false;
int numrows = matrix.size();
if (numrows == 0) return result;
int numcols = matrix[0].size();
if (numcols == 0) return result;
recursion(matrix, 0, 0, target, result, numrows, numcols);
return result;
}
void recursion(vector<vector<int>>& matrix, int i, int j, int target, bool& result, int numrows, int numcols)
{
if (i >= numrows || j >= numcols) return;
if (target == matrix[i][j]) {
result = true;
return;
}
if (target < matrix[i][j]) return;
//向下DFS
if (!result) recursion(matrix, i + 1, j, target, result, numrows, numcols);
//向右DFS
if (!result) recursion(matrix, i, j + 1, target, result, numrows, numcols);
return;
}
};
//方法二:网友的DFS
class Solution {
public:
bool dfs(int x, int y, vector<vector<int>>& matrix, int target) {
if (x < 0 || y < 0) {
return false;
}
else if (matrix[x][y] == target) {
return true;
}
else if (matrix[x][y] < target) {
return false;
}
matrix[x][y] = target - 1;
return dfs(x - 1, y, matrix, target) || dfs(x, y - 1, matrix, target);
}
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int row = matrix.size();
if (row == 0) {
return false;
}
int col = matrix[0].size();
if (col == 0) {
return false;
}
return dfs(row - 1, col - 1, matrix, target);
}
};
//方法三:巧妙思维法,从二维数组的左下角出发(只能向上走或是向右走),经过每一步判断,如果到了边界还没找到,说明不存在
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int rowNum = matrix.size();
if (rowNum == 0) {
return false;
}
int colNum = matrix[0].size();
if (colNum == 0) {
return false;
}
int rIdx = rowNum-1;
int cIdx = 0;
while (rIdx >= 0 && cIdx<colNum) {
if (matrix[rIdx ][cIdx] == target)
return true;
else if (matrix[rIdx][cIdx] > target)
rIdx -= 1;
else
cIdx += 1;
}
return false;
}
};