题目是LeetCode No.463 岛屿的周长

官方给的解答是遍历一遍矩阵。借着这个题目,学习一下在矩阵中进行DFS操作。

题目

  • 给定一个包含 0 和 1 的二维网格地图,其中 1 表示陆地 0 表示水域。
  • 网格中的格子水平和垂直方向相连(对角线方向不相连)。整个网格被水完全包围,但其中恰好有一个岛屿(或者说,一个或多个表示陆地的格子相连组成的岛屿)。
  • 岛屿中没有“湖”(“湖” 指水域在岛屿内部且不和岛屿周围的水相连)。格子是边长为 1 的正方形。网格为长方形,且宽度和高度均不超过 100。计算这个岛屿的周长。

示例

输入

[[0,1,0,0],
[1,1,1,0],
[0,1,0,0],
[1,1,0,0]]

输出: 16

解释:它的周长是下面图片中的 16 个黄色的边(如下图)

DFS遍历的方法

在类似的矩阵网格问题中,大致的题目轮廓均为m×n个小方格,组成一个网络,求网络中数量问题。

对于每一个小方格来说,有上、下、左、右四个方向可能存在相邻的方格,因此,DFS每次进行时要进行四个方向:

/**
* 矩阵方格DFS基本代码框架
* @param grid 二维矩阵
* @param r row:行
* @param c column:列
*/
void dfs(int[][] grid, int r, int c) {if(边界条件){return;}if(判断条件){code···}dfs(grid, r - 1, c);    // 上边相邻dfs(grid, r + 1, c);    // 下边相邻dfs(grid, r, c - 1);    // 左边相邻dfs(grid, r, c + 1);    // 右边相邻
}

在这一道题目中,对于一个陆地格子的每条边,它被算作岛屿的周长当且仅当这条边为网格的边界或者相邻的另一个格子为水域。 但是,对于网格边缘的放个,上下左右并不一定有相邻的方格,因此,需要增加边界判断条件!(0 <= r && r < grid.length && 0 <= c && c < grid[0].length)。如果满足了边界条件,说明位置非法,直接退出当前DFS即可。并且,当且仅当grid[r][c] == 0的时候,方格才为岛屿。因此,代码优化为:

void dfs(int[][] grid, int r, int c) {if (!(0 <= r && r < grid.length && 0 <= c && c < grid[0].length)) {return;}if (grid[r][c] != 1) {return;}dfs(grid, r - 1, c);    // 上边相邻dfs(grid, r + 1, c);    // 下边相邻dfs(grid, r, c - 1);    // 左边相邻dfs(grid, r, c + 1);    // 右边相邻
}

显然,我们的代码仍然存在一个问题:我们不知道每一个方格是否已经被遍历过。因此,我们需要一个二维数组(或者直接改变原始二维数组的值)来记录每一个方格是否已经被遍历过。在追求空间复杂度更低的情况下,直接改变原始二维数组即可。
因此,DFS代码进一步优化为:

void dfs(int[][] grid, int r, int c) {if (!(0 <= r && r < grid.length && 0 <= c && c < grid[0].length)) {return;}if (grid[r][c] != 1) {return;}grid[r][c] = X; // X根据题目设定,只要可以区别是否遍历即可dfs(grid, r - 1, c);    // 上边相邻dfs(grid, r + 1, c);    // 下边相邻dfs(grid, r, c - 1);    // 左边相邻dfs(grid, r, c + 1);    // 右边相邻
}

代入本题

思路

在本题中,遍历的过程中,如果方格值为1,说明岛屿+1,如果方格值为0,岛屿+0。因此,只要将DFS设置为带有返回值的函数,并根据方格值返回1或者0即可。

代码

int dfs(int[][] grid, int r, int c) {// 边界条件if (!(0 <= r && r < grid.length && 0 <= c && c < grid[0].length)) {return 1;}if (grid[r][c] == 0) {return 1;}if (grid[r][c] != 1) {return 0;}grid[r][c] = 2;return dfs(grid, r - 1, c) + dfs(grid, r + 1, c) + dfs(grid, r, c - 1) + dfs(grid, r, c + 1);}

Java编程:矩阵网格类算法问题做DFS相关推荐

  1. Java编程中“为了性能”尽量要做的26点

    最近的机器内存又爆满了,除了新增机器内存外,还应该好好review一下我们的代码,有很多代码编写过于随意化,这些不好的习惯或对程序语言的不了解是应该好好打压打压了. 下面是参考网络资源总结的一些在Ja ...

  2. java 计算矩阵行列式,【算法】递归算法之n阶矩阵行列式求解

    最近高等代数正好讲到这里,此篇文章正好对所学知识做一个具体程序实践. 设计算法时使用递归的思想是一个程序员的基本素质,递归可以把一个很庞大的问题转化为规模缩小了的同类问题的子问题,通过这一思想,我们编 ...

  3. JAVA编程中的类和对象

    1:初学JAVA,都知道JAVA是面向对象的编程.笔者这节开始说说类和对象.(实例仅供参考,如若复制粘贴记得修改包名和类名,避免出错) 学习JAVA的快捷键,Alt+/代码补全功能,其实此快捷键启动了 ...

  4. Java编程思想——复用类

    7 复用类 复用代码是java众多引人注目的功能之一.关于达到这个目的的方法有两种:一是只需在新的类中产生现有类的对象.由于新的类是现有类的对象所组成,这种方法称之为组合:第二种方法是按照现有类的类型 ...

  5. Java编程之学生类

    一.题目 编写一个学生类Student,属性包括:学号.姓名.年龄和成绩,数据由键盘进行输入且数据自拟,实现如下操作: 1.所有属性的getter和setter方法以及类的有参和无参构造方法: 2.将 ...

  6. Java高级工具类,任务1 JAVA编程高级-工具类.ppt

    课堂笔记: * * 课堂笔记: * 课堂笔记: 课堂笔记: * * 课堂笔记: 课堂笔记: * * 课堂笔记: * 课堂笔记: 课堂笔记: * * 课堂笔记: * 课堂笔记: 课堂笔记: * 课堂笔记 ...

  7. java宋江,Java编程内功-数据结构与算法「单链表」,

    package com.structures.linkedlist; public class SingleLinkedListDemo { public static void main(Strin ...

  8. java定义一个类计算圆的半径,C++编程:定义一个圆类要求属性为半径,操作为计算圆的周长和面积...,java编程:定义一个圆类,属性为半径,方法为对输入的半径计...

    导航:网站首页 > C++编程:定义一个圆类要求属性为半径,操作为计算圆的周长和面积...,java编程:定义一个圆类,属性为半径,方法为对输入的半径计 C++编程:定义一个圆类要求属性为半径, ...

  9. java类求圆的面积周长_java编程 1. 设计一个求圆的面积和周长的类,要求:1计算当半径r,JAVA编程题。编写一个应用程序计算圆的周长和面积,设圆的半...

    问题标题 java编程 1. 设计一个求圆的面积和周长的类,要求:1计算当半径r,JAVA编程题.编写一个应用程序计算圆的周长和面积,设圆的半 2019-5-23来自ip:15.196.194.53的 ...

  10. 岛屿类-网格类问题-DFS | 力扣200. 岛屿数量

    本文讲解200. 岛屿数量问题,属于常见的岛屿类-网格类问题 本题使用DFS的思想 1 题目 给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量. 岛屿总是被水包围, ...

最新文章

  1. VMware12中安装CentOS7.2的详细过程
  2. 2018春季德国第八届工业4.0考察之旅正式启航
  3. python下载word文件-python-docx操作word文件(
  4. 二、1、怎么做都好做,没flag就抓包
  5. c语言error c4430,error C4430: 缺少类型说明符 - 假定为 int。 异常怎么解决
  6. 音视频技术开发周刊 67期
  7. 网络流专题(最大流与费用流)(一)
  8. 小程序影藏溢出的gif_ScreenToGif:一款小巧实用动图gif制作神器
  9. 淘宝如何保障业务稳定性——诺亚(Noah)自适应流控
  10. 设置element-iu中table滚动条位置
  11. quick time不可用_教程|用Selenium爬资源:DIY还是花钱?
  12. MAC系统镜像几个版本的下载链接
  13. 绘制ER图:PowerDesigner数据库设计软件讲解
  14. python制作简单动画_如何使用python制作简单的动画?
  15. BilSTM 实体识别_“万创杯”中医药天池大数据竞赛——中药说明书实体识别挑战的一点感受...
  16. win7设置锁屏壁纸
  17. linux 有道笔记,Linux笔记:manjaro_折腾笔记
  18. Web前端:中国环宇科技有限公司网页设计
  19. 【opencv4.3.0教程】11之调整图像边缘(copyMakeBorder 与 borderInterpolate)
  20. 【SQL注入】手工注入常用语句合集

热门文章

  1. 11. Swoole 与 ThinkPHP
  2. 4. Javascript 函数
  3. js中的onscroll的用法
  4. 微服务架构一直火,为什么服务化要搞懂?
  5. 使用jQuery快速高效制作网页交互特效(6)
  6. mysql 大树据表update很慢
  7. 细数那些不能直视的IE6BUG
  8. Spring定时器技术终结者——采用XML配置的方式实现Spring定时器
  9. pom.xml mvn package expected START_TAG or END_TAG not TEXT
  10. Sql Server对时间(月、周)的操作