当前位置: 首页 > news >正文

【leetcode hot 100 994】腐烂的橘子

多源广度优先搜索

  • 所有的腐烂橘子在广度优先搜索上是等价于同一层的节点的。
  • 假设这些腐烂橘子刚开始是新鲜的,而有一个腐烂橘子(我们令其为超级源点)会在下一秒把这些橘子都变腐烂,而这个腐烂橘子刚开始在的时间是 −1,那么按照广度优先搜索的算法,下一分钟也就是第 0分钟的时候,这个腐烂橘子会把它们都变成腐烂橘子,然后继续向外拓展,所以其实这些腐烂橘子是同一层的节点。那么在广度优先搜索的时候,我们将这些腐烂橘子都放进队列里进行广度优先搜索即可,最后每个新鲜橘子被腐烂的最短时间 dis[x][y] 其实是以这个超级源点的腐烂橘子为起点的广度优先搜索得到的结果。
  • 为了确认是否所有新鲜橘子都被腐烂,可以记录一个变量 cnt 表示当前网格中的新鲜橘子数,广度优先搜索的时候如果有新鲜橘子被腐烂,则 cnt=cnt−1 ,最后搜索结束时如果 cnt 大于 0,说明有新鲜橘子没被腐烂,返回 −1 ,否则返回所有新鲜橘子被腐烂的时间的最大值即可,也可以在广度优先搜索的过程中把已腐烂的新鲜橘子的值由 1 改为 2,最后看网格中是否有值为 1 即新鲜的橘子即可。
class Solution {
    // 用于上下左右移动
    int[] row = new int[]{0, 1, 0, -1};
    int[] col = new int[]{1, 0, -1, 0};

    public int orangesRotting(int[][] grid) {
        int r = grid.length;
        int c = grid[0].length;

        // 先把所有烂了的橘子放入队列中
        Queue<Integer> queue = new ArrayDeque<>();
        Map<Integer, Integer> map = new HashMap<>();  // <橘子, 第几秒烂的>
        for(int i=0; i<r; i++){
            for(int j=0; j<c; j++){
                if(grid[i][j]==2){
                    int location = i*c + j;   // 用一个数标识二维数组的位置
                    queue.add(location);
                    map.put(location, 0);
                }
            }
        }

        // 烂橘子感染所有好橘子
        int ret = 0;
        while(!queue.isEmpty()){
            int node = queue.remove();
            int node_r = node/c;
            int node_c = node%c;
            for(int k=0; k<4; k++){
                // 得到四周的橘子
                int i = node_r + row[k];
                int j = node_c + col[k];
                if(i>=0 && i<r && j>=0 && j<c && grid[i][j]==1){ //记得判断ij的范围
                    // 好的橘子被感染
                    grid[i][j] = 2;
                    int location = i*c+j;
                    queue.add(location);
                    map.put(location, map.get(node)+1);
                    ret = map.get(location);
                }
            }
        }

        // 查看是否有好的橘子
        for(int[] row:grid){
            for(int v:row){
                if(v==1){
                    return -1;
                }
            }
        }
        return ret;
    }
}

注意:

  • queue用于广度优先遍历;map用于存储<腐烂的橘子location,第几秒烂的>
  • 在感染四周的好橘子的时候,要记得判断ij的范围
  • LinkedList和ArrayDeque的区别:
    • 操作:
      ArrayDeque:add() remove()
      LinkedList:offer() poll() peek()

    • 底层实现:
      ArrayDeque:基于可变长的数组和双指针来实现。
      LinkedList:基于双向链表来实现。

    • 支持的元素
      ArrayDeque:不支持存储 null 数据。
      LinkedList:支持存储 null 数据。

    • 引入版本
      ArrayDeque:在 JDK 1.6 中被引入。
      LinkedList:早在 JDK 1.2 中就已经存在。

    • 插入性能
      ArrayDeque:插入时可能存在扩容过程,但均摊后的插入操作依然为 O(1)。
      LinkedList:每次插入数据时均需要申请新的堆空间,均摊性能相比更慢。

参考:

Java ArrayDeque 与 LinkedList 的区别?

相关文章:

  • MongoDB 更新集合名
  • UML(统一建模语言)中总共有哪些图
  • VLLM专题(三十六)—自动前缀缓存
  • 当Anaconda的安装路径与我想创建的conda虚拟环境路径不一致时,应该怎么操作?
  • STM32-汇编
  • 【漫话机器学习系列】143.轮廓系数(Silhouette Coefficient)
  • QT 磁盘文件 教程03-创建、删除、复制文件
  • numpy学习笔记2:ones = np.ones((2, 4)) 的详解
  • PostgreSQL中array_to_string函数来将数组转换成逗号分隔的字符串
  • C#:深入理解Thread.Sleep与Task.Delay
  • 类和对象C++
  • 鸿蒙数据持久化之首选项
  • WebGL学习2
  • Echarts 折线图
  • 【Linux笔记】动态库与静态库的理解与加载
  • 《数字图像处理》第三章 灰度变换与空间滤波学习笔记(3.1-3.2)反转、对数、幂律、分段线性等变换
  • 【QT:QSS】
  • 在 MySQL 中,只写 JOIN 等价于?
  • linux 命令 mkdir
  • Spring中DI与IOC的关系解析
  • asp网站空间申请/精品成品网站1688
  • wordpress 评论显示图片/专业排名优化工具
  • 信息管理网站开发的视频教程/引擎搜索有哪些
  • 企业建设电商网站/建站平台如何隐藏技术支持
  • 网站做链接的意义是什么/seo网络推广专员
  • 东莞 网站 建设 雕塑/网站搭建平台都有哪些