cpp
#include<vector>
#include<iostream>
using namespace std;
int infection(vector<vector<int>> & vec,int x,int y,int T,int target)
{
int m=vec.size();
int n=vec[0].size();
if(x<0|| x>=m || y<0 || y>=n ||vec[x][y]==-1)
{
return 0;
}
if(abs(vec[x][y]-target)>T)
return 0;
vec[x][y]=-1;
int a=infection(vec,x+1,y,T,target);
int b=infection(vec,x-1,y,T,target);
int c=infection(vec,x,y+1,T,target);
int d=infection(vec,x,y-1,T,target);
return a+b+c+d+1;
}
int func(vector<vector<int>> & vec,int x,int y,int T)
{
int a=vec[x][y];
return infection(vec,x,y,T,a);
}
int main()
{
int m;
cin>>m;
int n;
cin>>n;
vector<vector<int>> vec(m,vector<int>(n,0));
int y;
cin>>y;
int x;
cin>>x;
int T;
cin>>T;
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
cin>>vec[i][j];
}
}
cout<<func(vec,x,y,T)<<endl;
return 0;
}
36.
#include<vector>
#include<string.h>
using namespace std;
class Solution {
public:
bool isValidSudoku(vector<vector<char>>& board)
{
int row[9][9];//rwo【i】【k】代表第i行的数字k-1出现的次数
int colmn[9][9];
int mrt[3][3][9];//mrt[i][j][k]代表的是,第i+1,j+1个框中,数字k-1出现的次数
memset(row,0,sizeof(row));
memset(colmn,0,sizeof(colmn));
memset(mrt,0,sizeof(mrt));
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
if(board[i][j]!='.')
{
int n=board[i][j]-'0'-1;
row[i][n]++;
colmn[j][n]++;
mrt[i/3][j/3][n]++;
if(row[i][n]>1 || colmn[j][n]>1|| mrt[i/3][j/3][n]>1)
{
return false;
}
}
}
}
return true;
}
};
48.
#include <iostream>
#include "vector"
#include <algorithm>
using namespace std;
//法一:使用额外的矩阵记录
//按行遍历,写入temp对应的列中
//第i行的第j个元素,就是temp里面的倒数第i列的第j个元素
class Solution {
public:
void rotate(vector<vector<int>>& matrix)
{
int m=matrix.size();
int n=matrix[0].size();
vector<vector<int>> temp(m,vector<int>(n,0));
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
temp[j][n-i-1]=matrix[i][j];
}
}
matrix=temp;
}
};
// 法二:原地旋转--不使用额外空间
// 这里的方法比较巧妙:以反转代替旋转。先上下反转,然后焱对角线反转
// 问:为什么可以这样反转? 答:上下反转是旋转-180后镜像,对角线反转是旋转270加一次镜像
class Solution {
public:
void rotate(vector<vector<int>>& matrix)
{
int m=matrix.size();
int n=matrix[0].size();
//先上下反转
for(int i=0;i<m/2;i++)
{
for(int j=0;j<n;j++)
{
swap(matrix[i][j],matrix[m-i-1][j]);
}
}
//再沿对角线反转
for(int i=0;i<m;i++)
{
for(int j=i+1;j<n;j++)
{
swap(matrix[i][j],matrix[j][i]);
}
}
return;
}
};
//翻转代替旋转
class Solution {
public:
void rotate(vector<vector<int>>& matrix)
{
int m=matrix.size();
int n=matrix[0].size();
//1 先上下反转
for(int i=0;i<m/2;i++)
{
for(int j=0;j<n;j++)
{
swap(matrix[i][j],matrix[m-i-1][j]);
}
}
//2 沿对角线反转
for(int i=0;i<m;i++)
{
for(int j=i+1;j<n;j++)
{
swap(matrix[i][j],matrix[j][i]);
}
}
return;
}
};
54.
#include<vector>
using namespace std;
//法一:在原矩阵上将遍历过的元素置空,来记录已经遍历过的元素
class Solution {
public:
int directions[4][2]={{0,1},{1,0},{0,-1},{-1,0}};//每一个{}代表的是方向。{}中第一个是行,第二个是列
vector<int> spiralOrder(vector<vector<int>>& matrix)
{
if(matrix.size()==0 || matrix[0].size()==0) return {};
int m=matrix.size();
int n=matrix[0].size();
vector<int > res;
int row=0;
int colmn=0;
int directionIndex=0;//记录的是当前遍历的方向。
for(int i=0;i<m*n;i++)
{
res.push_back(matrix[row][colmn]);
matrix[row][colmn]=101;
int nextrow=row+directions[directionIndex][0];
int nextcolmn=colmn+directions[directionIndex][1];
if(nextrow<0|| nextrow>=m || nextcolmn<0 || nextcolmn>=n || matrix[nextrow][nextcolmn]==101)
{
directionIndex=(directionIndex+1)%4;
}
//处理row和colmn
row=row+directions[directionIndex][0];
colmn=colmn+directions[directionIndex][1];
}
return res;
}
};
//法二:使用一个额外的数组来记录遍历过的元素
class Solution {
public:
int directions[4][2]={{0,1},{1,0},{0,-1},{-1,0}};//每一个{}代表的是方向。{}中第一个是行,第二个是列
vector<int> spiralOrder(vector<vector<int>>& matrix)
{
if(matrix.size()==0 || matrix[0].size()==0)
return {};
int m=matrix.size();
int n=matrix[0].size();
vector<int> res;
vector<vector<int>> mark(m,vector<int>(n,0));
int row=0;//当前遍历到的行
int colmn=0;//当前遍历到的列
int direction=0;//当前遍历的方向
for(int i=0;i<m*n;i++)
{
res.push_back(matrix[row][colmn]);
mark[row][colmn]=1;
int nextrow=row+directions[direction][0];
int nextcolmn=colmn+directions[direction][1];
if(nextrow<0 || nextrow>=m || nextcolmn<0 || nextcolmn>=n || mark[nextrow][nextcolmn]==1)
{
direction=(direction+1)%4;
}
row=row+directions[direction][0];
colmn=colmn+directions[direction][1];
}
return res;
}
};
59.
#include<vector>
using namespace std;
class Solution {
public:
int derections[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
vector<vector<int>> generateMatrix(int n)
{
int derectionindex=0;
int row=0;
int colmn=0;
vector<vector<int>> matrix(n,vector<int>(n,0));
for(int i=1;i<=n*n;i++)
{
matrix[row][colmn]=i;
int nextrow=row+derections[derectionindex][0];
int nextcolmn=colmn+derections[derectionindex][1];
if(nextrow>=n || nextrow<0 || nextcolmn>=n|| nextcolmn<0|| matrix[nextrow][nextcolmn]!=0)
{
derectionindex=(derectionindex+1)%4;
}
row=row+derections[derectionindex][0];
colmn=colmn+derections[derectionindex][1];
}
return matrix;
}
};
73
#include <vector>
using namespace std;
//简单--基本操作即可
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix)
{
int m=matrix.size();
int n=matrix[0].size();
vector<int> row;
vector<int> colmn;
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(matrix[i][j]==0)
{
row.push_back(i);
colmn.push_back(j);
}
}
}
//将行置零
for(int i=0;i<row.size();i++)
{
//将某一行置零
for(int h=0;h<n;h++)
{
matrix[row[i]][h]=0;
}
}
//将列置零
for(int i=0;i<colmn.size();i++)
{
for(int l=0;l<m;l++)
{
matrix[l][colmn[i]]=0;
}
}
return;
}
};
//法一的另一种写法
//遍历法
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix)
{
vector<int> twozero;
vector<int> colmnzero;
int m=matrix.size();
int n=matrix[0].size();
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(matrix[i][j]==0)
{
twozero.push_back(i);
colmnzero.push_back(j);
}
}
}
for(int i=0;i<twozero.size();i++)
{
for(int j=0;j<n;j++)
{
matrix[twozero[i]][j]=0;
}
}
for(int i=0;i<colmnzero.size();i++)
{
for(int j=0;j<m;j++)
{
matrix[j][colmnzero[i]]=0;
}
}
return;
}
};
79.
#include<vector>
#include<unordered_set>
using namespace std;
//递归搜索---类似于岛屿问题
//注意,这里有个小问题,就是,我们要记录当前搜索下已经使用过的元素,防止在一条搜索中重复使用某个元素(比如绕圈).
//这里使用的方法是,对于当前搜索,将使用过的元素设为空,然后进入下一条搜索的时候恢复!
class Solution {
public:
bool exist(vector<vector<char>>& board, string word)
{
for(int i=0;i<board.size();i++)
{
for(int j=0;j<board[0].size();j++)
{
if(infect(board,i,j,word))
return true;
}
}
return false;
}
bool infect(vector<vector<char>>& board,int i,int j,string& s)
{
if(s.size()==0)
return true;
if(i<0 || j<0 || i>=board.size()|| j>=board[0].size())
return false;
if(board[i][j]!=s[0])
return false;
char temp=board[i][j];
board[i][j]='\0';//记录遍历了
string temps= s.substr(1,s.size()-1);
bool a=infect(board,i-1,j,temps);
bool b=infect(board,i+1,j,temps);
bool c=infect(board,i,j+1,temps);
bool d=infect(board,i,j-1,temps);
board[i][j]=temp;//恢复
return a||b||c||d;
}
};
//另一种写法
class Solution {
public:
bool exist(vector<vector<char>>& board, string word)
{
int n=board.size();
int m=board[0].size();
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(infect(board,i,j,word,0))
return true;
}
}
return false;
}
bool infect(vector<vector<char>>& board,int i,int j,string& s,int k)
{
if(k==s.size())
return true;
if(i<0 || j<0 || i>=board.size()|| j>=board[0].size())
return false;
if(board[i][j]!=s[k])
return false;
char temp=board[i][j];
board[i][j]='\0';//记录遍历了
bool a=infect(board,i-1,j,s,k+1);
bool b=infect(board,i+1,j,s,k+1);
bool c=infect(board,i,j+1,s,k+1);
bool d=infect(board,i,j-1,s,k+1);
board[i][j]=temp;//恢复
return a||b||c||d;
}
};
130.
#include<string>
#include<vector>
using namespace std;
class Solution {
public:
void solve(vector<vector<char>>& board)
{
int m=board.size();
if(m<=2) return ;
int n=board[0].size();
//1 找边界上的O,并进行感染的过程,即将与边界的O接触的O全部标记上
for(int i=0;i<n;i++)
{
dfs(board,0,i);
dfs(board,m-1,i);
}
for(int i=1;i<m-1;i++)
{
dfs(board,i,0);
dfs(board,i,n-1);
}
//2 根据记号进行重写
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (board[i][j] == 'A') {
board[i][j] = 'O';
} else if (board[i][j] == 'O') {
board[i][j] = 'X';
}
}
}
return ;
}
void dfs(vector<vector<char>>& board,int i,int j)
{
//base_case
if(i<0 || i>=board.size() || j<0|| j>=board[0].size() || board[i][j]!='0')
{
return;
}
board[i][j]='A';
dfs(board,i+1,j);
dfs(board,i-1,j);
dfs(board,i,j+1);
dfs(board,i,j-1);
}
};
200.
#include<vector>
#include<string>
using namespace std;
//岛屿感染问题
//my
class Solution {
public:
int numIslands(vector<vector<char>>& grid)
{
int m=grid.size();
int n=grid[0].size();
int res=0;
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(grid[i][j]=='1')
{
res++;
infection(i,j,grid);
}
}
}
return res;
}
//实现感染。将从i,j开始的相邻的1全部变成0
void infection(int i,int j,vector<vector<char>>& grid)
{
int m=grid.size();
int n=grid[0].size();
//base_case
if(i<0 || i>=m || j<0 || j>=n || grid[i][j]=='0')
{
return;
}
grid[i][j]='0';
infection(i+1,j,grid);
infection(i-1,j,grid);
infection(i,j+1,grid);
infection(i,j-1,grid);
}
};
#include<string>
#include<vector>
using namespace std;
class Solution {
public:
int maxAreaOfIsland(vector<vector<int>>& grid)
{
int m=grid.size();
int n=grid[0].size();
int count=0;
int res=0;
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(grid[i][j]==1)
{
count=infection(grid,i,j);
res=max(res,count);
}
}
}
return res;
}
//返回的是矩阵中,ij为中心的,感染的格子的数量
int infection(vector<vector<int>> & grid,int i,int j)
{
int m=grid.size();
int n=grid[0].size();
//base_case
if(i<0 || j<0 || i>=m || j>=n || grid[i][j]==0)
{
return 0;
}
grid[i][j]=0;
int a=infection(grid,i+1,j);
int b=infection(grid,i-1,j);
int c=infection(grid,i,j-1);
int d=infection(grid,i,j+1);
return 1+a+b+c+d;
}
};
JZ04
#include<vector>
using namespace std;
class Solution {
public:
bool findNumberIn2DArray(vector<vector<int>>& matrix, int target)
{
if(matrix.size()==0 )
return false;
int n=matrix.size();//行数
int m=matrix[0].size();//列数
int i=0;//第一行
int j=m-1;//第一列
while(i<n && j>=0)
{
if(matrix[i][j]==target)
return true;
else if(matrix[i][j]>target)
j--;
else if(matrix[i][j]<target)
i++;
}
return false;;
}
};
JZ13.
#include<vector>
using namespace std;
class Solution {
public:
int movingCount(int m, int n, int k)
{
vector<vector<int>> mark(m,vector<int>(n,0));
return foot(m,n,k,0,0,mark);
}
//表示从i,j开始走,得到的最大的格子数
int foot(int m,int n,int k,int i,int j,vector<vector<int>> & mark)
{
//base_case
if(i<0|| i>=m|| j<0 ||j>=n)
return 0;
if((i/10+i%10+j/10+j%10)>k)
return 0;
if(mark[i][j]==1)
return 0;
mark[i][j]=1;
int a=foot(m,n,k,i+1,j,mark);
int b=foot(m,n,k,i-1,j,mark);
int c=foot(m,n,k,i,j+1,mark);
int d=foot(m,n,k,i,j-1,mark);
return 1+a+b+c+d;
}
};
NOTE
对于矩阵的搜索,往往需要记录已经访问过的格子,通常有两种方法:
- 使用一个单独的相同大小的矩阵来记录,访问过的置1
- 在原矩阵上,将遍历过的元素置空,遍历到某个位置的时候,先判断这个位置是不是为空。
矩阵以及搜索
最新推荐文章于 2024-09-05 23:31:31 发布