【LeetCode热题100】打卡第37天:岛屿数量反转链表

news2024/11/24 15:31:16

文章目录

  • 【LeetCode热题100】打卡第37天:岛屿数量&反转链表
    • ⛅前言
  • 岛屿数量
    • 🔒题目
    • 🔑题解
  • 反转链表
    • 🔒题目
    • 🔑题解

【LeetCode热题100】打卡第37天:岛屿数量&反转链表

⛅前言

大家好,我是知识汲取者,欢迎来到我的LeetCode热题100刷题专栏!

精选 100 道力扣(LeetCode)上最热门的题目,适合初识算法与数据结构的新手和想要在短时间内高效提升的人,熟练掌握这 100 道题,你就已经具备了在代码世界通行的基本能力。在此专栏中,我们将会涵盖各种类型的算法题目,包括但不限于数组、链表、树、字典树、图、排序、搜索、动态规划等等,并会提供详细的解题思路以及Java代码实现。如果你也想刷题,不断提升自己,就请加入我们吧!QQ群号:827302436。我们共同监督打卡,一起学习,一起进步。

博客主页💖:知识汲取者的博客

LeetCode热题100专栏🚀:LeetCode热题100

Gitee地址📁:知识汲取者 (aghp) - Gitee.com

Github地址📁:Chinafrfq · GitHub

题目来源📢:LeetCode 热题 100 - 学习计划 - 力扣(LeetCode)全球极客挚爱的技术成长平台

PS:作者水平有限,如有错误或描述不当的地方,恳请及时告诉作者,作者将不胜感激

岛屿数量

🔒题目

原题链接:200.岛屿数量

image-20230714100415618

🔑题解

  • 解法一:DFS

    对于这种搜索类的题目,DFS和BFS是一个比较直接的思想

    1. 我们需要遍历每一个节点,每一个节点都有可能成为搜索的起始点
    2. 然后将每一个搜索过的点,进行标记,下一次搜索就直接跳过
    3. 我们需要遍历前后左右四点

    image-20230714130352282

    /**
     * @author ghp
     * @title
     * @description
     */
    class Solution {
        public int numIslands(char[][] grid) {
            int n = grid.length;
            int m = grid[0].length;
            int count = 0;
            boolean[][] vis = new boolean[n][m];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    if (!vis[i][j] && grid[i][j] != '0') {
                        // 当前节点没有遍历过,并且不是水,则进行深度搜索
                        dfs(grid, vis, i, j);
                        count++;
                    }
                }
            }
            return count;
        }
    
        private void dfs(char[][] grid, boolean[][] vis, int i, int j) {
            if (i < 0 || i > grid.length-1 || j < 0 || j > grid[0].length-1 || grid[i][j] == '0') {
                // 超出范围或遇到水,结束搜索
                return;
            }
            if (vis[i][j]){
                // 节点已遍历
                return;
            }
            // 将已遍历的节点标记为true
            vis[i][j] = true;
            // 往右遍历
            dfs(grid, vis, i, j + 1);
            // 往左遍历
            dfs(grid, vis, i, j - 1);
            // 往下遍历
            dfs(grid, vis, i + 1, j);
            // 往上遍历
            dfs(grid, vis, i - 1, j);
        }
    }
    

    复杂度分析:

    • 时间复杂度: O ( n ∗ m ) O(n*m) O(nm),需要遍历每一个节点
    • 空间复杂度: O ( n ∗ m ) O(n*m) O(nm),vis数组空间占用 n ∗ m n*m nm,递归调用如果全是陆地,则需要递归 n ∗ m n*m nm次,如果全是水,或者水和陆地均衡分布,只需要递归1次

    其中 n n n 为数组的行, m m m为数组的列

    代码优化:空间优化

    前面我们使用一个vis数组来记录节点是否遍历,由于我们对于每一个节点只需要遍历一遍,所以可以直接将遍历过的节点置为0,即可,所以可以直接省略掉vis数组

    class Solution {
        public int numIslands(char[][] grid) {
            int count = 0;
            for (int i = 0; i < grid.length; i++) {
                for (int j = 0; j < grid[0].length; j++) {
                    if (grid[i][j] != '0') {
                        dfs(grid, i, j);
                        count++;
                    }
                }
            }
            return count;
        }
    
        private void dfs(char[][] grid, int i, int j) {
            if (i < 0 || i > grid.length - 1 || j < 0 || j > grid[0].length - 1 || grid[i][j] == '0') {
                // 超出范围或遇到水,结束搜索
                return;
            }
            grid[i][j] = '0';
            // 往右遍历
            dfs(grid, i, j + 1);
            // 往左遍历
            dfs(grid, i, j - 1);
            // 往下遍历
            dfs(grid, i + 1, j);
            // 往上遍历
            dfs(grid, i - 1, j);
        }
    }
    
  • 解法二:BFS

    一般能用DFS的题目都可以使用BFS来解决,实现思路也比较简单,本题是一个很规范的BFS和DFS的题

    import java.util.LinkedList;
    import java.util.Queue;
    
    /**
     * @author ghp
     * @title
     * @description
     */
    class Solution {
        public int numIslands(char[][] grid) {
            int count = 0;
            for (int i = 0; i < grid.length; i++) {
                for (int j = 0; j < grid[0].length; j++) {
                    if (grid[i][j] != '0') {
                        // 不是水,则可以进行搜索
                        bfs(grid, i, j);
                        count++;
                    }
                }
            }
            return count;
        }
    
        private void bfs(char[][] grid, int i, int j) {
            // 方向数组:上、下、左、右
            int[][] direction = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
            Queue<int[]> queue = new LinkedList<>();
            // 搜索起始节点
            queue.add(new int[]{i, j});
            // 开始广度搜索
            while (!queue.isEmpty()) {
                // 回到上一个点的位置
                int[] cur = queue.poll();
                i = cur[0];
                j = cur[1];
                // 遍历四个方向
                for (int k = 0; k < 4; k++) {
                    int a = i + direction[k][0];
                    int b = j + direction[k][1];
                    if (0 <= a && a < grid.length && 0 <= b && b < grid[0].length && grid[a][b] != '0') {
                        queue.add(new int[]{a, b});
                        grid[a][b] = '0';
                    }
                }
            }
        }
    }
    

    复杂度分析:

    • 时间复杂度: O ( n ∗ m ) O(n*m) O(nm)
    • 空间复杂度: O ( m i n ( n , m ) ) O(min(n,m)) O(min(n,m)),即使最坏情况,整个网格都是陆地,队列的中的元素最多是 min(n,m)

    其中 n n n 为数组的行, m m m为数组的列

  • 解法三:并查集(详情看LeetCode官网)

    这题我们只需要掌握好前面两种解法即可

    class Solution {
        class UnionFind {
            int count;
            int[] parent;
            int[] rank;
    
            public UnionFind(char[][] grid) {
                count = 0;
                int m = grid.length;
                int n = grid[0].length;
                parent = new int[m * n];
                rank = new int[m * n];
                for (int i = 0; i < m; ++i) {
                    for (int j = 0; j < n; ++j) {
                        if (grid[i][j] == '1') {
                            parent[i * n + j] = i * n + j;
                            ++count;
                        }
                        rank[i * n + j] = 0;
                    }
                }
            }
    
            public int find(int i) {
                if (parent[i] != i) parent[i] = find(parent[i]);
                return parent[i];
            }
    
            public void union(int x, int y) {
                int rootx = find(x);
                int rooty = find(y);
                if (rootx != rooty) {
                    if (rank[rootx] > rank[rooty]) {
                        parent[rooty] = rootx;
                    } else if (rank[rootx] < rank[rooty]) {
                        parent[rootx] = rooty;
                    } else {
                        parent[rooty] = rootx;
                        rank[rootx] += 1;
                    }
                    --count;
                }
            }
    
            public int getCount() {
                return count;
            }
        }
    
        public int numIslands(char[][] grid) {
            if (grid == null || grid.length == 0) {
                return 0;
            }
    
            int nr = grid.length;
            int nc = grid[0].length;
            int num_islands = 0;
            UnionFind uf = new UnionFind(grid);
            for (int r = 0; r < nr; ++r) {
                for (int c = 0; c < nc; ++c) {
                    if (grid[r][c] == '1') {
                        grid[r][c] = '0';
                        if (r - 1 >= 0 && grid[r-1][c] == '1') {
                            uf.union(r * nc + c, (r-1) * nc + c);
                        }
                        if (r + 1 < nr && grid[r+1][c] == '1') {
                            uf.union(r * nc + c, (r+1) * nc + c);
                        }
                        if (c - 1 >= 0 && grid[r][c-1] == '1') {
                            uf.union(r * nc + c, r * nc + c - 1);
                        }
                        if (c + 1 < nc && grid[r][c+1] == '1') {
                            uf.union(r * nc + c, r * nc + c + 1);
                        }
                    }
                }
            }
    
            return uf.getCount();
        }
    }
    
    作者:LeetCode
    链接:https://leetcode.cn/problems/number-of-islands/solution/dao-yu-shu-liang-by-leetcode/
    来源:力扣(LeetCode)
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    

反转链表

🔒题目

原题链接:206.反转链表

image-20230714131704461

🔑题解

  • 解法一:暴力

    public class Solution {
        public ListNode reverseList(ListNode head) {
            if (head == null){
                return null;
            }
            List<Integer> list = new ArrayList<>();
            while (head != null){
                list.add(head.val);
                head = head.next;
            }
            Collections.reverse(list);
            ListNode newHead = new ListNode(list.remove(0));
            ListNode p = newHead;
            while (!list.isEmpty()){
                p.next = new ListNode(list.remove(0));
                p = p.next;
            }
            return newHead;
        }
    }
    

    复杂度分析:

    • 时间复杂度: O ( n ) O(n) O(n)
    • 空间复杂度: O ( n ) O(n) O(n)

    其中 n n n 为链表节点的数量

  • 解法二:双指针迭代实现

    image-20230714133700394

    public class Solution {
        public ListNode reverseList(ListNode head) {
            ListNode pre = null;
            ListNode cur = head;
            while (cur != null){
                ListNode next = cur.next;
                cur.next = pre;
                pre = cur;
                cur = next;
            }
            return pre;
        }
    }
    

    复杂度分析:

    • 时间复杂度: O ( n ) O(n) O(n)
    • 空间复杂度: O ( 1 ) O(1) O(1)

    其中 n n n 为数组中元素的个数

  • 解法三:双指针递归实现

    image-20230714135134246

    public class Solution {
        public ListNode reverseList(ListNode head) {
            if (head == null || head.next == null){
                return head;
            }
            ListNode newHead = reverseList(head.next);
            head.next.next = head;
            head.next = null;
            return newHead;
        }
    }
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/752442.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

kettle开发-Day41-数据清洗之字符串替换

前言&#xff1a; 昨天讲到了通过case/switch组件来进行分流&#xff0c;来区分日期里面三大类的数据&#xff0c;包括正常显示的2023/7/12 2:59:58的数据&#xff0c;一种是包含中文上午的数据&#xff0c;一种是包含中文下午的数据。但是我们发现这样直接存进去的数据还是包含…

时间有界 梦想无疆(NEBASE第十三课)

时间有界 梦想无疆(NEBASE第十三课) 1、计算机网络功能 数据通信、资源共享、增加数据可靠性、提高系统处理能力&#xff08;主要功能数所通信&#xff09; 2.标准&#xff1a;一致同意的规则可以理解为标谁 ISO&#xff08;国际标准化组织&#xff09;在网络通信中创建了OS…

前端学习——JS进阶 (Day1)

作用域 局部作用域 全局作用域 作用域链 JS垃圾回收机制 闭包 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name&qu…

walkRE2019--属性批量赋值

1、选中待赋值的图形&#xff0c;在加工菜单栏中选择属性赋值&#xff0c;如下&#xff1a; 选择图形所在图层&#xff0c;并使图层处于可编辑状态。选择要赋值的属性字段&#xff08;即要更新的列&#xff09;&#xff0c;选择要赋值的表达式&#xff08;即赋值为&#xff09;…

产品经理必备技能:高效产品规划方法论

作为产品经理&#xff0c;进行产品规划是非常重要的一项工作。产品规划是一个方法化的过程&#xff0c;需要考虑多个因素&#xff0c;以确保产品能够满足用户需求并实现商业目标。以下是几点建议&#xff0c;帮助产品经理进行产品规划。 第一&#xff0c;了解用户需求和市场情况…

【Unity编辑器扩展】编辑器代码一键添加按钮响应事件

此功能能是基于UI变量代码生成工具的改良扩展&#xff1a;【Unity编辑器扩展】UI变量代码自动生成工具(编辑器扩展干货/大幅提高效率)_ui代码自动生成_TopGames的博客-CSDN博客 工具效果预览&#xff1a; UGUI的Button按钮在编辑面板添加响应事件非常繁琐&#xff0c;需要拖个…

视频孪生在数字经济产业发展中所发挥的作用

2023年中共中央、国务院印发的《数字中国建设整体布局规划》中明确提出&#xff1a;培育壮大数字经济核心产业&#xff0c;研究制定推动数字产业高质量发展的措施&#xff0c;打造具有国际竞争力的数字产业集群。 推动数字技术和实体经济深度融合&#xff0c;在农业、工业、金…

七大排序算法——堆排序,通俗易懂的思路讲解与图解(完整Java代码)

文章目录 一、排序的概念排序的概念排序的稳定性七大排序算法 二、堆排序核心思想代码实现 三、性能分析四、七大排序算法 一、排序的概念 排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递…

emacs下vercial-border审美观记录

昨天一晚上时间都花在了emacs的vercial-border上。 一开始还不知道这个名词&#xff0c;以为是treemacs展示的效果&#xff0c;毕竟我是在打开treemacs的时候&#xff0c;才发现这个分割线太丑了,我的审美观在蠢蠢欲动了。 谁说程序员没有审美观的&#xff1f;只是前面有别的东…

一文带你快速设计精美可视化大屏

一文带你快速设计精美可视化大屏 文章目录 一文带你快速设计精美可视化大屏&#x1f468;‍&#x1f3eb;前言&#xff1a;什么是可视化大屏&#x1f468;‍&#x1f52c;内容1&#xff1a;可视化大屏设计原则和设计考虑&#x1f468;‍⚖️内容2&#xff1a;可视化大屏设计流程…

第四章 数学知识(三)——高斯消元,组合

文章目录 高斯消元组合数1 < b < a < 20001 < b < a < 1000001 < b < a < 1 0 18 10^{18} 1018高精度组合数卡特兰数 高斯消元练习题884. 高斯消元解异或线性方程组 组合数练习题885. 求组合数 I886. 求组合数 II887. 求组合数 III888. 求组合数 I…

【AUTOSAR】:NvM

Autosar的NvM理解 AUTOSAR_SWS_NVRAMManager.pdf块的定义块的管理类型块的状态重点梳理:几个常用的API函数AUTOSAR_SWS_MemoryAbstractionInterface.pdf里面对存储的HAL抽象衍生出几个重要的MainFunctionNV (non volatile):非亦失性,也就是我们需要将数据存储到Flash或外部E…

谈谈企业未来如何实现有序用电

摘 要&#xff1a;风光发电的大比例发展将对电网需要的转动惯量和备用产生致命影响&#xff0c;严重威胁电网的平稳运行&#xff0c;本文结合AcrelEMS企业微电网系统谈谈企业如何应对。 关键词&#xff1a;有序用电 调节负荷 综合能源管理 企业微电网 0 引言 自2020年9月以来&…

android linker加载和链接机制

文章目录 So的加载和启动So文件的读取与加载工作ReadProgramHeaderReserveAddressSpaceLoadSegmentsFindPhdr so 的链接机制动态节区 执行so文件原文地址&#xff1a; So的加载和启动 handledlopen(pathName,PTLD_LAZY)&#xff1b;//获得指定文件的句柄&#xff0c;这个handl…

SpringAMQP - 消息传输时,如何提高性能?解决 SQL 注入问题?

目录 一、问题背景 二、从消息转化器根源解决问题 1.引入依赖 2.在服务生产者和消费者中都重新定义一个 MessageConverter&#xff0c;注入到 Spring 容器中 一、问题背景 在SpringAMQP的发送方法中&#xff0c;接收消息的类型是Object&#xff0c;也就是说我们可以发送任意…

【程序人生】如何在工作中保持稳定的情绪?

前言 在工作中保持稳定的情绪是现代生活中一个备受关注的话题。随着职场压力和工作挑战的增加&#xff0c;我们常常发现自己情绪波动不定&#xff0c;甚至受到负面情绪的困扰。然而&#xff0c;保持稳定的情绪对于我们的工作效率、人际关系和整体幸福感都至关重要。 无论你是…

GPT-4揭秘:从科学突破到宇宙探索,大模型如何为人类谋福祉?

最近一段时间&#xff0c;人工智能领域似乎在上演一场密切相关的三幕戏。从OpenAI的GPT-4&#xff0c;到LeanDojo的开源平台&#xff0c;再到Elon Musk的xAI&#xff0c;人工智能的最新发展进程仿佛正在向我们揭示未来的模样。让我们深入探讨一下这些最新的科技发展。 GPT-4&a…

个人信息保护影响评估,推动个人信息保护“关口前移”

2021 年 11 月 1 日&#xff0c;《个人信息保护法》&#xff08;以下简称《个保法》&#xff09;的正式施行&#xff0c;可以说在我国个人信息保护法治建设具有里程碑意义。《个保法》内容具备系统性、针对性和可操作性特点&#xff0c;规范了个人信息处理活动&#xff0c;明确…

ubuntu安装软件包提示【未安装软件包 deepin-elf-verify】【已解决】

文章目录 背景原因分析步骤1 解压文件2 删除依赖3 重新打包软件 转载请标明出处&#xff1a; https://bigmaning.blog.csdn.net/article/details/131713280 本文出自:【BigManing的博客】 背景 在ubuntu系统上安装一个deb文件&#xff0c;执行命令后&#xff0c;报错如下 sud…

【C++】STL之string功能及模拟实现

目录 前沿 一、标准库中的string类 二、string类的常用接口说明 1、string类对象的常见构造 2、string类对象的容量操作 3、string类对象的访问及遍历操作 4、string类对象的修改操作 5、string类非成员函数 6、vs下string结构的说明 三、string类的模拟实现 1、构造函数 2…