LeetCode 力扣官方题解 - 1020. 飞地的数量

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 力扣官方题解 - 1020. 飞地的数量相关的知识,希望对你有一定的参考价值。

参考技术A

题目描述

给你一个大小为 m x n 的二进制矩阵 grid,其中 0 表示一个海洋单元格、1 表示一个陆地单元格。

一次 移动 是指从一个陆地单元格走到另一个相邻(上、下、左、右)的陆地单元格或跨过 grid 的边界。

返回网格中 无法 在任意次数的移动中离开网格边界的陆地单元格的数量。


示例 1:

示例 2:

提示:


根据飞地的定义,如果从一个陆地单元格出发无法移动到网格边界,则这个陆地单元格是飞地。因此可以将所有陆地单元格分成两类:第一类陆地单元格和网格边界相连,这些陆地单元格不是飞地;第二类陆地单元格不和网格边界相连,这些陆地单元格是飞地。

我们可以从网格边界上的每个陆地单元格开始深度优先搜索,遍历完边界之后,所有和网格边界相连的陆地单元格就都被访问过了。然后遍历整个网格,如果网格中的一个陆地单元格没有被访问过,则该陆地单元格不和网格的边界相连,是飞地。

代码实现时,由于网格边界上的单元格一定不是飞地,因此遍历网格统计飞地的数量时只需要遍历不在网格边界上的单元格。


代码

Java


C#


C++


C

Python3

Golang

JavaScript

复杂度分析

也可以通过广度优先搜索判断每个陆地单元格是否和网格边界相连。

首先从网格边界上的每个陆地单元格开始广度优先搜索,访问所有和网格边界相连的陆地单元格,然后遍历整个网格,统计飞地的数量。

代码

Java

C#

C++

C

Python3

Golang

JavaScript

复杂度分析

除了深度优先搜索和广度优先搜索的方法以外,也可以使用并查集判断每个陆地单元格是否和网格边界相连。

并查集的核心思想是计算网格中的每个陆地单元格所在的连通分量。对于网格边界上的每个陆地单元格,其所在的连通分量中的所有陆地单元格都不是飞地。如果一个陆地单元格所在的连通分量不同于任何一个网格边界上的陆地单元格所在的连通分量,则该陆地单元格是飞地。

并查集的做法是,遍历整个网格,对于网格中的每个陆地单元格,将其与所有相邻的陆地单元格做合并操作。由于需要判断每个陆地单元格所在的连通分量是否和网格边界相连,因此并查集还需要记录每个单元格是否和网格边界相连的信息,在合并操作时更新该信息。

在遍历网格完成并查集的合并操作之后,再次遍历整个网格,通过并查集中的信息判断每个陆地单元格是否和网格边界相连,统计飞地的数量。

代码

Java

C#

C++

C

Python3

Golang

JavaScript

复杂度分析


BY /

本文作者:力扣

LeetCode 罗马数字转整数

13. 罗马数字转整数

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/roman-to-integer
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


在这里插入图片描述

理解题意

罗 马 数 字 转 整 数 力 扣 官 方 题 解 \\mathbf 罗马数字转整数_{力扣官方题解}

  • 罗马符号对应数字进行相加
  • 罗马符号特例:两个字符组成;左边对应数字小于右边;右边减去左边所得
  • 其实罗马符号特例只有IV、IX、XL、XC、CD、CM

Map保存对应罗马数字

class Solution {
    public int romanToInt(String s) {
        HashMap<Character, Integer> romanValue = new HashMap<Character, Integer>();
        romanValue.put('I', 1);
        romanValue.put('V', 5);
        romanValue.put('X', 10);
        romanValue.put('L', 50);
        romanValue.put('C', 100);
        romanValue.put('D', 500);
        romanValue.put('M', 1000);

        int sum = 0;
        int preNum = 0;
        for (int i = 0; i < s.length(); i++) {
            int num = romanValue.get(s.charAt(i));
            if (preNum < num) {
                sum -= preNum;
            } else {
                sum += preNum;
            }
            preNum = num;
        }
        sum += preNum;
        return sum;
    }
}

在这里插入图片描述

Switch判断对应罗马数字

class Solution {
     public int romanToInt(String s) {
        int sum = 0;
        int preNum = 0;
        for (int i = 0; i < s.length(); i++) {
            int num = getRomanValue(s.charAt(i));
            if (preNum < num) {
                sum -= preNum;
            } else {
                sum += preNum;
            }
            preNum = num;
        }
        sum += preNum;
        return sum;
    }

    private int getRomanValue(char ch) {
        switch (ch) {
            case 'I':
                return 1;
            case 'V':
                return 5;
            case 'X':
                return 10;
            case 'L':
                return 50;
            case 'C':
                return 100;
            case 'D':
                return 500;
            case 'M':
                return 1000;
            default:
                return 0;
        }
    }
}

在这里插入图片描述

Switch判断+特殊罗马数字

class Solution {
    public int romanToInt(String s) {
        s.replace("IV", "a");//`IV、IX、XL、XC、CD、CM`
        s.replace("IX", "b");
        s.replace("XL", "e");
        s.replace("XC", "f");
        s.replace("CD", "g");
        s.replace("CM", "h");

        int sum = 0;
        int preNum = 0;
        for (int i = 0; i < s.length(); i++) {
            int num = getRomanValue(s.charAt(i));
            if (preNum < num) {
                sum -= preNum;
            } else {
                sum += preNum;
            }
            preNum = num;
        }
        sum += preNum;
        return sum;
    }

    private int getRomanValue(char ch) {
        switch (ch) {
            case 'I':
                return 1;
            case 'V':
                return 5;
            case 'X':
                return 10;
            case 'L':
                return 50;
            case 'C':
                return 100;
            case 'D':
                return 500;
            case 'M':
                return 1000;
            case 'a':
                return 4;
            case 'b':
                return 9;
            case 'e':
                return 40;
            case 'f':
                return 90;
            case 'g':
                return 400;
            case 'h':
                return 900;
            default:
                return 0;
        }
    }
}

结果查看特殊罗马处理反而消耗更多时间和内存
在这里插入图片描述

以上是关于LeetCode 力扣官方题解 - 1020. 飞地的数量的主要内容,如果未能解决你的问题,请参考以下文章

力扣(LeetCode)整数反转 个人题解

力扣LeetCode-300. 最长递增子序列-题解

力扣LeetCode-300. 最长递增子序列-题解

155.最小栈-力扣(LeetCode)

155.最小栈-力扣(LeetCode)

力扣(LeetCode)颠倒二进制位 个人题解