给你一个由若干 0 和 1 组成的二维网格 grid ,其中 0 表示水,而 1 表示陆地。岛屿由水平方向或竖直方向上相邻的 1(陆地)连接形成。

如果恰好只有一座岛屿 ,则认为陆地是连通的 ;否则,陆地就是分离的 。一天内,可以将任何单个陆地单元(1)更改为水单元(0)。返回使陆地分离的最少天数。
示例 1: 输入:grid = [[0,1,1,0],[0,1,1,0],[0,0,0,0]] 输出:2 解释:至少需要 2天才能得到分离的陆地。 将陆地 grid[1][1] 和 grid[0][2] 更改为水,得到两个分离的岛屿。
示例 2: 输入:grid = [[1,1]]
输出:2 解释:如果网格中都是水,也认为是分离的 ([[1,1]] -> [[0,0]]),0 岛屿。
示例 3: 输入:grid = [[1,0,1,0]] 输出:0
示例 4: 输入:grid = [
[1,1,0,1,1],
[1,1,1,1,1],
[1,1,0,1,1],
[1,1,0,1,1]] 输出:1
示例 5: 输入:grid = [
[1,1,0,1,1],
[1,1,1,1,1],
[1,1,0,1,1],
[1,1,1,1,1]] 输出:2

花了一段时间想到答案不是0就是1,不是1就是2。判断是否是0挺简单的,找到一个1计算连通的1的个数,并与grid中1的总数进行比较。判断是否是1就比较麻烦了,直接的想法是挨个删一删试试,用和上面相同的办法进行判断:

class Solution {int countLand(int[][] grid, int row, int col) {grid[row][col] = 0;int ans = 1;if(row < grid.length - 1 && grid[row + 1][col] == 1) {ans += countLand(grid, row + 1, col);}if(col < grid[0].length - 1 && grid[row][col + 1] == 1) {ans += countLand(grid, row, col + 1);}if(row > 0 && grid[row - 1][col] == 1) {ans += countLand(grid, row - 1, col);}if(col > 0 && grid[row][col - 1] == 1) {ans += countLand(grid, row, col - 1);}return ans; }boolean isSplit(int[][] grid, int num) {if(num == 0)return true;if(num == 1)return false;//找到第一个1 搜索 比较连通的陆地大小是不是陆地总大小for(int i = 0; i < grid.length; ++i)for(int j = 0; j < grid[0].length; ++j) {if(grid[i][j] == 1) {int[][] copy = new int[grid.length][];for (int ii = 0; ii < grid.length; ii++) {copy[ii] = new int[grid[ii].length];System.arraycopy(grid[ii], 0, copy[ii], 0, grid[ii].length);}return countLand(copy, i, j) != num;}}return false;} public int minDays(int[][] grid) {//还真被吓到了//答案最大不超过2int num = 0;for(int i = 0; i < grid.length; ++i) for(int j = 0; j < grid[0].length; ++j) {if(grid[i][j] == 1)++num;}if(isSplit(grid, num)) {return 0;}for(int i = 0; i < grid.length; ++i) for(int j = 0; j < grid[0].length; ++j) {if(grid[i][j] == 1) {grid[i][j] = 0;if(isSplit(grid, num - 1)) {return 1;}grid[i][j] = 1;}}return 2;}
}

27ms 居然没有超时。
看了看别人的参考,有说用Tarjan法的,搜了一下,这篇感觉写的挺好的:Tarjan法求割点。基本上是dfs并对搜索到的树进行判断。判断自己和子树靠返回边能到的序号和父节点的序号,如果返回边等到达的序号不小于父节点的序号,那去了父节点肯定完蛋。实现了一下:

class Solution {int countLand(int[][] grid, int row, int col) {grid[row][col] = 0;int ans = 1;if(row < grid.length - 1 && grid[row + 1][col] == 1) {ans += countLand(grid, row + 1, col);}if(col < grid[0].length - 1 && grid[row][col + 1] == 1) {ans += countLand(grid, row, col + 1);}if(row > 0 && grid[row - 1][col] == 1) {ans += countLand(grid, row - 1, col);}if(col > 0 && grid[row][col - 1] == 1) {ans += countLand(grid, row, col - 1);}return ans; }boolean isSplit(int[][] grid, int num) {if(num == 0)return true;if(num == 1)return false;//找到第一个1 搜索 比较连通的陆地大小是不是陆地总大小for(int i = 0; i < grid.length; ++i)for(int j = 0; j < grid[0].length; ++j) {int[][] copy = new int[grid.length][];for (int ii = 0; ii < grid.length; ii++) {copy[ii] = new int[grid[ii].length];System.arraycopy(grid[ii], 0, copy[ii], 0, grid[ii].length);}if(grid[i][j] == 1 && countLand(copy, i, j) != num) {return true;}}return false;} int curDfn;int[][] dfn;int[][] low;int firstChilds;boolean cut;void processPoint(int[][] grid, int curR, int curC, int nextR, int nextC, int from) {if(cut == true)return;if(dfn[nextR][nextC] == 0) {++curDfn;dfn[nextR][nextC] = curDfn;low[nextR][nextC] = curDfn;dfs(grid, nextR, nextC, from);low[curR][curC] = Math.min(low[curR][curC], low[nextR][nextC]);if(dfn[curR][curC] != 1 && low[nextR][nextC] >= dfn[curR][curC])cut = true;if(dfn[curR][curC] == 1)++firstChilds;} else {low[curR][curC] = Math.min(low[curR][curC], low[nextR][nextC]);}}void dfs(int[][] grid, int row, int col, int from) {if(cut == true)return;if(row < grid.length - 1 && grid[row + 1][col] == 1 && from != 0) {processPoint(grid, row, col, row + 1, col, 2);}if(col < grid[0].length - 1 && grid[row][col + 1] == 1 && from != 1) {processPoint(grid, row, col, row, col + 1, 3);}if(row > 0 && grid[row - 1][col] == 1 && from != 2) {processPoint(grid, row, col, row - 1, col, 0);}if(col > 0 && grid[row][col - 1] == 1 && from != 3) {processPoint(grid, row, col, row, col - 1, 1);}}boolean hasCut(int[][] grid) {cut = false;dfn = new int[grid.length][grid[0].length];//维护访问次序low = new int[grid.length][grid[0].length];//维护回溯能达到的最小数值for(int i = 0; i < grid.length; ++i) for(int j = 0; j < grid[0].length; ++j){if(grid[i][j] == 1) {dfn[i][j] = 1;low[i][j] = 1;curDfn = 1;dfs(grid, i, j, -1);return cut || firstChilds > 1;}}return cut;}public int minDays(int[][] grid) {int num = 0;for(int i = 0; i < grid.length; ++i) for(int j = 0; j < grid[0].length; ++j) {if(grid[i][j] == 1)++num;}if(isSplit(grid, num)) {return 0;}if(hasCut(grid)) {return 1;}return 2;}
}

因为是在方法1基础上改的,所以对于初始情况的判别用的和上次一样的方法。居然是74ms…怎么正经做反而慢了啊

周末加餐 使陆地分离的最少天数相关推荐

  1. LeetCode 1568. 使陆地分离的最少天数(DFS)

    文章目录 1. 题目 2. 解题 1. 题目 给你一个由若干 0 和 1 组成的二维网格 grid ,其中 0 表示水,而 1 表示陆地. 岛屿由水平方向或竖直方向上相邻的 1 (陆地)连接形成. 如 ...

  2. leetcode1568. 使陆地分离的最少天数(Python3、c++)

    文章目录 leetcode1568. 使陆地分离的最少天数 方法:并查集 思路: 并查集: 求割点: 代码: Python3: cpp: 结果: leetcode1568. 使陆地分离的最少天数 给你 ...

  3. 五、c++学习(加餐1:汇编基础学习)

    经过前面几节课的学习,我们在一些地方都会使用汇编来分析,我们学习汇编,只是学习一些基础,主要是在我们需要深入分析语法的时候,使用汇编分析,这样会让我们更熟悉c++编译器和语法. 从这节课开始,会持续加 ...

  4. 【加餐】如何在SteamVR 2 中替换手部模型

    根据学员朋友的反馈,新增3节加餐课时,关于如何在新版SteamVR中基于Skeleton Input实现手部模型的替换. 在VR应用程序中,要呈现自制的手部模型,传统的方式是直接将模型导入,放置在手柄 ...

  5. Lesson13【加餐】 损失函数的随机创建现象详解

    [Lesson 13 加餐]损失函数的随机创建现象详解   接下来,我们通过手动创建一个实例,来观察在小批梯度下降过程中,损失函数是如何根据数据数据变化而变化的,这里既是作为本节内容的一个补充,同时也 ...

  6. 旋转矩阵求旋转角度_(加餐)欧拉角及矩阵旋转

    (1 本文约2000字,大约需要阅读20分钟)(2 本文适合有一定雷达及信号与系统知识基础的读者) 乡亲们大家好,今天的这期内容就像有钱人的生活,比较枯燥,不过能完整读下来也确能有所收获,本文是分析微 ...

  7. LeetCode 1674. 使数组互补的最少操作次数(差分思想)

    文章目录 1. 题目 2. 解题 1. 题目 给你一个长度为 偶数 n 的整数数组 nums 和一个整数 limit . 每一次操作,你可以将 nums 中的任何整数替换为 1 到 limit 之间的 ...

  8. LeetCode 1653. 使字符串平衡的最少删除次数(DP)

    文章目录 1. 题目 2. 解题 1. 题目 给你一个字符串 s ,它仅包含字符 'a' 和 'b'​​​​ . 你可以删除 s 中任意数目的字符,使得 s 平衡 . 我们称 s 平衡的 当不存在下标 ...

  9. 使括号有效的最少添加

    使括号有效的最少添加 给定一个由(和)括号组成的字符串S,我们需要添加最少的括号(或是),可以在任何位置,以使得到的括号字符串有效. 从形式上讲,只有满足下面几点之一,括号字符串才是有效的: 它是一个 ...

最新文章

  1. 二维物体形状识别方法比较
  2. python使用fpdf将生成的长字符串手动换行写入pdf
  3. Javascript 绑定事件和 this理解
  4. java面向对象的特征三:多态性 —(15)
  5. java 线程什么时候出栈_在Java中给出的时间
  6. html:(17):img标签和表单标签
  7. C++STL与泛型编程(3)容器之分类与测试
  8. 【实践】BiLSTM上的CRF,用命名实体识别任务来解释CRF(2)损失函数
  9. 线报采集监控|人工智能+线报采集算法+大数据过滤无效线报
  10. 生物信息预测毒力因子
  11. 五险一金,这篇就够了
  12. 解决win10可以登录微信/QQ,浏览器无法访问网页的问题
  13. [转] 从1个月到2岁半的育儿方案,有了它宝宝都不用去上早教啦
  14. Java基础系列-《流程控制--循环结构》
  15. 数分下(第1讲):一阶微分方程的三类模型求解
  16. LSL学习笔记(4)
  17. 使用 AIX TCP/IP 过滤功能设置防火墙
  18. 视觉SLAM:一直在入门,从未到精通
  19. 组图:1936年柏林奥运会
  20. 柠檬水找零---贪心算法(c++)实现

热门文章

  1. js实现gbk编码转utf字符串
  2. 天寒地冻正是读书好时节
  3. 【汉化】Construct 2 bate r247汉化中文版
  4. 谈谈如何降低(减少)AMD显卡发热量的问题
  5. 已知空间圆弧曲线的两点以及圆心半径,用matlab画出圆弧
  6. 今日头条2017校园招聘 春招4.18笔试
  7. Eclipse下open iExplorer插件安装
  8. 2019年报腾讯的业绩跷跷板:B端升起C端落下
  9. POJ1716-Integer Intervals
  10. 5728系统刷机步骤