LeetCode算法入门 day9 广度优先搜索 / 深度优先搜索

542. 01 矩阵

给定一个由 0 和 1 组成的矩阵 mat ,请输出一个大小相同的矩阵,其中每一个格子是 mat 中对应位置元素到最近的 0 的距离。

两个相邻元素间的距离为 1 。

示例 1:
在这里插入图片描述

输入:mat = [[0,0,0],[0,1,0],[0,0,0]]
输出:[[0,0,0],[0,1,0],[0,0,0]]

示例 2:
在这里插入图片描述

输入:mat = [[0,0,0],[0,1,0],[1,1,1]]
输出:[[0,0,0],[0,1,0],[1,2,1]]

头一次打算完完整整不看题解自己写完,但是高估了自己,写了好久好久,实在搞不出来就找别人的代码看。要注意边界,否则就会调好久好久好久。话说为什么用c++不行,改成Java就行了呢,难搞。
代码:

class Solution {
//深度优先搜索
    int dx[]={1,0,0,-1};
    int dy[]={0,1,-1,0};
    void dfs(int[][] mat,int x,int y){//[x][y]已知,求[x][y]四个方向的值      
        int m=mat.length,n=mat[0].length; 
        for(int i=0;i<4;i++){
                int mx = x+dx[i],my = y+dy[i];
                if(mx>=0&&mx<m&&my>=0&&my<n&&mat[mx][my]>mat[x][y]+1){
                    mat[mx][my] = mat[x][y] +1;
                    dfs(mat,mx,my);
                }
        }     
    }
    boolean Zeronear(int[][] mat,int x,int y){//四个方向有没有0
        int m=mat.length,n=mat[0].length; 
        for(int i=0;i<4;i++){
            int nextx=x+dx[i],nexty=y+dy[i];
            if(nextx>=0&&nexty>=0&&nextx<m&&nexty<n&&mat[nextx][nexty]==0) //在矩阵内且值为0
                return true;
        }
        return false;
      
    }
    public int[][] updateMatrix(int[][] mat) {       
        int m=mat.length;
        if(m==0) return mat;
        int n=mat[0].length;
       
       
        //初始化mat矩阵,把值为1且四方无0的位置赋值为无穷大,可以用较大的数代替
        for(int i=0;i<m;i++){          
            for(int j=0;j<n;j++){              
                if(Zeronear(mat,i,j)==false&&mat[i][j]==1)//该元素=1,且四个方向没有0
                    mat[i][j]=Integer.MAX_VALUE;
            }
        }

        for(int i=0;i<m;i++){          
            for(int j=0;j<n;j++){              
                if(mat[i][j]==1)//该元素=1,从等于1的元素开始,向内递归
                    {dfs(mat,i,j);}
            }
        }
        return mat;
    }
};

994. 腐烂的橘子

在给定的 m x n 网格 grid 中,每个单元格可以有以下三个值之一:

值 0 代表空单元格;
值 1 代表新鲜橘子;
值 2 代表腐烂的橘子。
每分钟,腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子都会腐烂。

返回 直到单元格中没有新鲜橘子为止所必须经过的最小分钟数。如果不可能,返回 -1 。

示例 1:

在这里插入图片描述

输入:grid = [[2,1,1],[1,1,0],[0,1,1]]
输出:4

示例 2:

输入:grid = [[2,1,1],[0,1,1],[1,0,1]]
输出:-1
解释:左下角的橘子(第 2 行, 第 0 列)永远不会腐烂,因为腐烂只会发生在 4 个正向上。

示例 3:

输入:grid = [[0,2]]
输出:0
解释:因为 0 分钟时已经没有新鲜橘子了,所以答案就是 0

代码:

class Solution {//广度优先搜索
public:
    int orangesRotting(vector<vector<int>>& grid) {
        int m=grid.size(),n=grid[0].size();
        int dx[4]={1,0,0,-1},dy[4]={0,1,-1,0};
        int fresh=0;//新鲜橘子数
        queue<int>q;
        for(int i=0;i<m;i++){//遍历,记录新鲜橘子数,将烂橘子加入队列
            for(int j=0;j<n;j++){
        //是2的话就记录该坐标是坏橘子,这里采用二维转一维,行数*总列数+列数——把矩阵铺开成一条线时对应的下标
                if(grid[i][j]==2) q.push(i*n+j);
                else if(grid[i][j]==1)fresh++;
            }
        }

        if(!fresh) return 0;//没有新鲜橘子
        int res=-1;
        while(!q.empty()){//只要有腐烂橘子
            int badSum=q.size();//当前轮次(对应层序遍历的一层)所含有多少个坏橘子
            while(badSum){
                int temp=q.front();//当前去感染其他橘子的烂橘子
                q.pop();
                int row=temp/n;//坐标还原
                int col=temp%n;//坐标还原
                for(int k=0;k<4;k++){//去感染四周
                    int newRow=row+dx[k];
                    int newCol=col+dy[k];
                    //被感染的两个条件 1.没有越界  2.有橘子且是新鲜橘子
                    if(newRow>=0&&newRow<m&&newCol>=0&&newCol<n&&grid[newRow][newCol]==1){
                        grid[newRow][newCol]=2;//标记感染过了
                        q.push(newRow*n+newCol);//下一轮就到这个坏橘去感染别橘
                        fresh--;
                    } 
                }
                badSum--;
            }
            res++;//一轮结束就+1
        }
        //感染完还有新鲜橘子剩的话,那个橘子是隔离橘,感染不到它的,按题意返回-1
        return fresh==0?res:-1;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值