【OJ】LeetCode——994. 腐烂的橘子

题目描述

在这里插入图片描述

思路

由题目可以看出,每次从一个已经腐烂的橘子向外层蔓延,不难看出这是在模拟广度优先搜索BFS的例程
因此我们所用到的就是BFS算法
大致过程如下:

  1. 首先遍历整个网格,找到已经腐烂的橘子,加入队列;
  2. 从已经腐烂的橘子去更新相邻的橘子,直到队列为空;
  3. 若队列为空,网格上还有新鲜橘子,返回-1,否则返回总时间

问题

但在实际编程中,却遇到了两个问题

1.入队数据

入队的数据应该是此时橘子的坐标,那么应该是什么数据类型?

2.烂橘子的扩散

如何去判断当前橘子的四个正方向坐标,数组的边界判定如何实现?

解决

1.

入队的数据的话,采取的方案就是计算当前坐标的代数值,如一个4*4的网格,左上角作为坐标原点,那么(2,2)的坐标代数值为2 *4 + 2 = 10
推广为一般化形式:
一个M x N的矩阵,(i, j)的坐标代数值= i * N + j

2.

关于四个正方向的判定问题采取的是官方的解答,即创建两个数组

int[] dr = new int[]{-1, 0, 1, 0};
int[] dc = new int[]{0, -1, 0, 1};

用一个4层循环 每次改变行/列的值
如果当前坐标(i,j)是合法的,并且该网格上的是新鲜的橘子,更新其值并入队列

for(int k=0; k<4; k++){
	int ni = i + dr[k];
    int nj = j + dc[k];
    if(ni>=0 && ni<grid.length && nj>=0 && nj<grid[0].length && grid[ni][nj]==1){
        grid[ni][nj] = 2;
        queue.add(ni*grid[0].length+nj);
    }
}

完整的代码

class Solution {
    public int orangesRotting(int[][] grid) {
        int[] dr = new int[]{-1, 0, 1, 0};
        int[] dc = new int[]{0, -1, 0, 1};

        int times = 0;
        Queue<Integer> queue = new LinkedList<>();

        //烂橘子入队
        for(int i=0; i<grid.length; i++){
            for(int j=0; j<grid[i].length; j++){
                if(grid[i][j] == 2)
                    queue.add(i*grid[0].length+j);//将坐标值入队
            }
        }

        while(!queue.isEmpty()){
            int i, j, t;
            int size = queue.size();
            for(int s=0; s<size; s++){
                t = queue.poll();
                i = t / grid[0].length;
                j = t % grid[0].length;
                for(int k=0; k<4; k++){
                    int ni = i + dr[k];
                    int nj = j + dc[k];
                    if(ni>=0 && ni<grid.length && nj>=0 && nj<grid[0].length && grid[ni][nj]==1){
                    grid[ni][nj] = 2;
                    queue.add(ni*grid[0].length+nj);
                    }
                }
            }
            if(!queue.isEmpty())
                times++;
        }

        for(int i=0; i<grid.length; i++){
            for(int j=0; j<grid[i].length; j++){
                if(grid[i][j] == 1)
                    return -1;
            }
        }

        return times;
    }
}

扩展1:广度优先搜索 BFS

基本策略

越早被访问到的顶点,其邻居越优先被选用

不难发现,广度优先搜索即树结构中层序遍历,用到的辅助结构为——队列
以下是邓俊辉《数据结构》中的样例:
在这里插入图片描述

扩展2:深度优先搜索 DFS

1. 基本策略

优先选取最后一个被访问到的顶点的邻居

本质上来说就是递归+回溯

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2. 注意事项

  • 算法遍历边和访问顶点的顺序与图的表示方式有关,而不只与图的结构和算法有关
  • DFS中,每条边都会被访问两次, 而且第二次为发现这个点已经被标记过了(已经访问过,不再重复访问)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值