994. Rotting Oranges
难度:
Easy
思路:
图论题,一个图中若干好橘子和若干坏橘子,每回合坏橘子周围的好橘子会坏掉,问第几回合后没有坏橘子。
比较流行的思路就是bfs,以坏橘子作为起点,一层层搜,搜完即可得到回合数
确实这种思维很好想,但比起bfs,普通按回合grow&check要好写多了
简简单单才是真,踏踏实实按回合走,思路清晰好写,而且代码效率极其高
代码:
/*
Author Owen_Q
*/
class Solution {
public:
int orangesRotting(vector<vector<int>>& grid) {
n = grid.size();
m = grid[0].size();
int day = 0;
int num = check(grid);
while(num>0)
{
day++;
grow(grid);
if(num>check(grid))
num = check(grid);
else
break;
}
if(num>0)
return -1;
else
return day;
}
private:
int n,m;
bool legal(int x,int y)
{
if(x<0||x>=n||y<0||y>=m)
return false;
else
return true;
}
int d[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
void grow(vector<vector<int>>& grid)
{
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(grid[i][j] == 2)
{
for(int k=0;k<4;k++)
{
int dx = i + d[k][0];
int dy = j + d[k][1];
if(legal(dx,dy)&&grid[dx][dy]==1)
{
grid[dx][dy] = 3;
}
}
}
}
}
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(grid[i][j] == 3)
grid[i][j] = 2;
return ;
}
int check(vector<vector<int>>& grid)
{
int sum = 0;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(grid[i][j] == 1)
sum++;
return sum;
}
};
59. Spiral Matrix II
难度:
Medium
思路:
螺旋形画图填数,那就总结规律咯
不难发现,每个螺旋四个方向,每个方向当成一个回合的话,对于规格为n的图形刚好2n-1个回合。除了第一回合,刚好每两个回合递减一次长度,于是,连定位都省了,直接按回合跑即可
当然,由于这里需要返回一个二维vector,如果需要模拟填数的话,这个vector的总框架必须提前定好,即初始化,下面回顾一下vector的初始化
STL知识回顾:
Vector 初始化
vector<int> v(a,b)
即表示定义一个int类型的vector v,里面有a个元素,值均为b
那么类比可得二维数组初始化方式:
初始化a行b列的二维数组所有值均为c
vector< vector<int> > v(a,vector<int>(b,c))
代码:
/*
Author Owen_Q
*/
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
int aa = 2, dd = 0, xx = 0, yy = 0, pp = -1, ss=n-1;
vector<vector<int>> re(n,vector<int>(n,0));
re[0][0] = 1;
while(ss>0)
{
drawline(aa,dd,xx,yy,pp,ss,re);
}
return re;
}
private:
int d0[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
void drawline(int &a,int &d,int &x,int &y,int &p, int &s, vector<vector<int>> &r)
{
for(int i=0;i<s;i++)
{
x += d0[d][0];
y += d0[d][1];
r[x][y] = a++;
}
d = (d+1) % 4;
p++;
if(p==2)
{
p = 0;
s--;
}
return ;
}
};