Leetcode 生命游戏

在这里插入图片描述
以下是上述Java代码的算法思想及其逻辑的中文解释:


算法思想

这段代码实现了LeetCode第289题“生命游戏”的解决方案。核心思想是:

  1. 利用原地修改的方式(in-place)存储下一状态的变化

    • 通过引入额外的状态值(23)来表示细胞的过渡状态。
    • 避免使用额外的存储空间(如创建新矩阵),提高了空间效率。
  2. 两步处理逻辑

    • 第一步:根据当前状态和邻居情况标记下一状态(过渡状态)。
    • 第二步:将过渡状态转换为最终状态。
  3. 状态定义

    • 0:死亡细胞,下一状态仍然死亡。
    • 1:存活细胞,下一状态仍然存活。
    • 2:存活细胞,下一状态变为死亡(过渡状态)。
    • 3:死亡细胞,下一状态变为存活(过渡状态)。

代码逻辑详解

第一步:遍历每个细胞,计算其活邻居数并标记过渡状态
for (int row = 0; row < rows; row++) {
    for (int col = 0; col < cols; col++) {
        int liveNeighbors = countLiveNeighbors(board, row, col);
        // 规则 1 和 3:存活细胞由于邻居过少(<2)或过多(>3)而死亡
        if (board[row][col] == 1 && (liveNeighbors < 2 || liveNeighbors > 3)) {
            board[row][col] = 2; // 标记为死亡
        }
        // 规则 4:死亡细胞由于正好有 3 个活邻居而复活
        if (board[row][col] == 0 && liveNeighbors == 3) {
            board[row][col] = 3; // 标记为复活
        }
    }
}
  • 遍历二维数组的每个细胞。
  • 调用辅助方法 countLiveNeighbors 来统计当前细胞的活邻居数。
  • 根据规则:
    • 如果当前细胞是存活的(1),但活邻居数少于2或多于3,则变为死亡(2)。
    • 如果当前细胞是死亡的(0),但活邻居数正好为3,则变为存活(3)。

第二步:将过渡状态更新为最终状态
for (int row = 0; row < rows; row++) {
    for (int col = 0; col < cols; col++) {
        if (board[row][col] == 2) {
            board[row][col] = 0; // 过渡状态 2 变为死亡
        } else if (board[row][col] == 3) {
            board[row][col] = 1; // 过渡状态 3 变为存活
        }
    }
}
  • 遍历整个数组,将细胞的过渡状态转化为最终状态:
    • 2 表示的“存活→死亡”变为 0
    • 3 表示的“死亡→存活”变为 1

辅助方法:统计当前细胞的活邻居数量
private int countLiveNeighbors(int[][] board, int row, int col) {
    int[] directions = {-1, 0, 1};
    int liveCount = 0;

    for (int dr : directions) {
        for (int dc : directions) {
            if (dr == 0 && dc == 0) continue; // 跳过当前细胞
            int newRow = row + dr;
            int newCol = col + dc;

            // 判断邻居是否在边界范围内,并检查其是否为活细胞
            if (newRow >= 0 && newRow < board.length && newCol >= 0 && newCol < board[0].length) {
                if (board[newRow][newCol] == 1 || board[newRow][newCol] == 2) {
                    liveCount++;
                }
            }
        }
    }

    return liveCount;
}
  • 通过方向数组 {-1, 0, 1} 遍历当前细胞的8个邻居。
  • 检查邻居是否越界,以及是否是活细胞。
  • 注意:过渡状态 2 仍然被视为活细胞。

复杂度分析

  1. 时间复杂度

    • 遍历矩阵 (O(m \times n)),每个细胞计算8个邻居的活细胞数 (O(1))。
    • 总时间复杂度为 (O(m \times n))。
  2. 空间复杂度

    • 使用原地修改,无需额外存储空间,空间复杂度为 (O(1))。

总结

  • 该算法通过原地修改矩阵,利用额外的状态值来避免使用额外空间。
  • 遵循了题目要求,按规则逐步更新细胞的状态,最终输出下一状态的生命游戏棋盘。
class Solution {
    public void gameOfLife(int[][] board) {
        int rows = board.length;
        int cols = board[0].length;

        //首先遍历每个细胞,统计其存活邻居数量,并标记过渡状态
        for(int i = 0; i < rows; i++) {
            for(int j = 0; j < cols; j++) {
                int liveneighbors = countLiveNeighbors(board, i, j);
                if((liveneighbors < 2 || liveneighbors > 3) && board[i][j] == 1) {
                    board[i][j] = 2;
                }
                if(countLiveNeighbors(board, i, j) == 3 && board[i][j] == 0) {
                    board[i][j] = 3;
                }
            }
        }

        //根据标记的过渡状态更新board
        for(int i = 0; i < rows; i++) {
            for(int j = 0; j < cols; j++) {
                if(board[i][j] == 2) {
                    board[i][j] = 0;
                }else if(board[i][j] == 3) {
                    board[i][j] = 1;
                }
            }
        }
        
        
    }

    private int countLiveNeighbors(int[][] board, int row, int col) {
        int[] directions = {-1, 0, 1};
        int livecount = 0;
        for(int dr : directions) {
            for(int dc : directions) {
                if(dr == 0 && dc == 0) continue; //跳过原地
                int newrow = row + dr;
                int newcol = col + dc;
                //判断邻居是否越界或存活
                
                if(newrow >= 0 && newrow < board.length && newcol >= 0 && newcol < board[0].length) {
                    if(board[newrow][newcol] == 1 || board[newrow][newcol] == 2) {
                        livecount++;
                    }
                }
            }
        }
        return livecount;
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

文件管理 IV(文件系统)

一、文件系统结构 文件系统&#xff08;File system&#xff09;提供高效和便捷的磁盘访问&#xff0c;以便允许存储、定位、提取数据。文件系统有两个不同的设计问题&#xff1a;第一个问题是&#xff0c;定义文件系统的用户接口&#xff0c;它涉及定义文件及其属性、所允许的…

单神经元 PID 解耦控制

单神经元 PID 解耦控制是一种将单神经元自适应控制与解耦控制相结合的方法&#xff0c;适用于多输入多输出&#xff08;MIMO&#xff09;系统。其核心是利用单神经元的自适应能力实现 PID 参数在线调整&#xff0c;同时通过解耦策略减少变量之间的相互影响&#xff0c;提高控制…

【青牛科技】电流模式PWM控制器系列--D4870

概述&#xff1a; D4870是用于开关电源的电流模式PWM(PWM)控制器系列产品。 该电路待机功耗低&#xff0c;启动电流低。在待机模式下&#xff0c;电路进入间歇工作模式&#xff0c;从而有效地降低电路的待机功耗。 电路的开关频率为 65KHz&#xff0c;抖动的振荡频率&…

【8210A-TX2】Ubuntu18.04 + ROS_ Melodic + TM-16多线激光 雷达评测

简介&#xff1a;介绍 TM-16多线激光雷达 在8210A载板&#xff0c;TX2核心模块环境&#xff08;Ubuntu18.04&#xff09;下测试ROS驱动&#xff0c;打开使用RVIZ 查看点云数据&#xff0c;本文的前提条件是你的TX2里已经安装了ROS版本&#xff1a;Melodic。 大家好&#xff0c;…

计算机毕设-基于springboot的高校网上缴费综合务系统视频的设计与实现(附源码+lw+ppt+开题报告)

博主介绍&#xff1a;✌多个项目实战经验、多个大型网购商城开发经验、在某机构指导学员上千名、专注于本行业领域✌ 技术范围&#xff1a;Java实战项目、Python实战项目、微信小程序/安卓实战项目、爬虫大数据实战项目、Nodejs实战项目、PHP实战项目、.NET实战项目、Golang实战…

在 macOS 和 Linux 中,波浪号 `~`的区别

文章目录 1、在 macOS 和 Linux 中&#xff0c;波浪号 ~macOS示例 Linux示例 区别总结其他注意事项示例macOSLinux 结论 2、root 用户的主目录通常是 /root解释示例切换用户使用 su 命令使用 sudo 命令 验证当前用户总结 1、在 macOS 和 Linux 中&#xff0c;波浪号 ~ 在 macO…

【SQL Server】华中农业大学空间数据库实验报告 实验九 触发器

1.实验目的 通过实验课程与理论课的学习深入理解掌握的触发器的原理、创建、修改、删除、基本的使用方法、主要用途&#xff0c;并且可以在练习的基础上&#xff0c;熟练使用触发器来进行数据库的应用程序的设计&#xff1b;深入学习深刻理解与触发器相关的T-SQL语句的编写的基…

小程序24-滚动效果:scroll-view组件详解

在微信小程序中如果想实现内容滚动&#xff0c;需要使用 scroll-view 组件 scroll-view&#xff1a;可滚动视图区域&#xff0c;适用于需要滚动展示内容的场景&#xff0c;用户可以通过手指滑动或者点击滚动条滚动内容。 scroll-x允许横向滚动scroll-y允许纵向滚动 实现横向…

Leetcode 分发糖果

这段代码的算法思想是 贪心算法&#xff0c;通过两次遍历&#xff0c;分别从左到右、从右到左调整糖果分配&#xff0c;以满足题目中相邻评分较高的孩子必须获得更多糖果的要求&#xff0c;并最终计算出最少需要分配的糖果总数。 以下是代码的详细思想与执行过程&#xff1a; …

39页PDF | 毕马威_数据资产运营白皮书(限免下载)

一、前言 《毕马威数据资产运营白皮书》探讨了数据作为新型生产要素在企业数智化转型中的重要性&#xff0c;提出了数据资产运营的“三要素”&#xff08;组织与意识、流程与规范、平台与工具&#xff09;和“四重奏”&#xff08;数据资产盘点、评估、治理、共享&#xff09;…

【Redis_Day5】String类型

【Redis_Day5】String类型 String操作String的命令set和get&#xff1a;设置、获取键值对mset和mget&#xff1a;批量设置、获取键值对setnx/setex/psetexincr和incrby&#xff1a;对字符串进行加操作decr/decrby&#xff1a;对字符串进行减操作incrbyfloat&#xff1a;浮点数加…

linux安装mysql57——笔记

rpm -qa | grep mysql有东西就rpm -e 文件名 下载 wget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm安装 yum -y install mysql57-community-release-el7-10.noarch.rpm安装 yum -y install mysql-community-server如果出现Error: GPG c…

基于Java Springboot高校会议室预订管理系统

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据…

基于 NCD 与优化函数结合的非线性优化 PID 控制

基于 NCD 与优化函数结合的非线性优化 PID 控制 1. 引言 NCD&#xff08;Normalized Coprime Factorization Distance&#xff09;优化是一种用于非线性系统的先进控制方法。通过将 NCD 指标与优化算法结合&#xff0c;可以在动态调整控制参数的同时优化控制器性能。此方法特别…

数据库表设计范式

华子目录 MYSQL库表设计&#xff1a;范式第一范式&#xff08;1NF&#xff09;第二范式&#xff08;2NF&#xff09;第三范式&#xff08;3NF&#xff09;三范式小结巴斯-科德范式&#xff08;BCNF&#xff09;第四范式&#xff08;4NF&#xff09;第五范式&#xff08;5NF&…

中国省级新质生产力发展指数数据(任宇新版本)2010-2023年

一、测算方式&#xff1a;参考C刊《财经理论与实践》任宇新&#xff08;2024&#xff09;老师的研究&#xff0c;新质生产力以劳动者劳动资料劳动对象及其优化组合的质变为 基本内涵&#xff0c;借 鉴 王 珏 和 王 荣 基 的 做 法构建新质生产力发展水平评价指标体系如下所示&a…

【爬虫】Firecrawl对京东热卖网信息爬取(仅供学习)

项目地址 GitHub - mendableai/firecrawl: &#x1f525; Turn entire websites into LLM-ready markdown or structured data. Scrape, crawl and extract with a single API. Firecrawl更多是使用在LLM大模型知识库的构建&#xff0c;是大模型数据准备中的一环&#xff08;在…

Admin.NET框架前端由于keep-alive设置缓存导致的onUnmount未触发问题

bug版本&#xff1a;next分支&#xff0c;基于.NET6版本&#xff1b; 问题描述&#xff1a; 1、添加keep-alive后&#xff0c;在其下运行的组件会出现onActived(被关注时)和onDeactived(取消关注时)生命周期&#xff0c;而组件原有生命周期为onMounted(被创造时)和onUnmounted(…

机器学习day7-线性回归3、逻辑回归、聚类、SVC

7欠拟合与过拟合 1.欠拟合 模型在训练数据上表现不佳&#xff0c;在新的数据上也表现不佳&#xff0c;常发生在模型过于简单无法处理数据中的复杂模式时。 特征&#xff1a; 训练误差较高 测试误差也高 模型过于简化&#xff0c;不能充分学习训练数据中的模式 2.过拟合 …

【鸿蒙开发】第二十二章 IPC与RPC进程间通讯服务

目录 1 IPC与RPC通信概述 2 实现原理 3 约束与限制 4 使用场景 5 开发步骤 5.1 Native侧开发步骤 5.2 ArkTS侧开发步骤 6 远端状态订阅开发实例 6.1 使用场景 6.1.1 Native侧接口 6.2 ArkTS侧接口 6.3 Stub感知Proxy消亡&#xff08;匿名Stub的使用&#xff09; 1 …