Leetcode 生命游戏

news2024/11/23 20:48:51

在这里插入图片描述
以下是上述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;
    }
}

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

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

相关文章

C++【面试重要题目】 只出现一次的数字的集合.

文章目录 前言一、前提要点补充二、题集总结 前言 本篇笔者将会对 cpp 中比较有意思的类型题目进行细致讲解 . 这类题同时也是面试中比较重要的算法题 , 其算法思想需要学者掌握. 以下题目均来自力扣 一、前提要点补充 ● 几个运用运算符 因为笔者介绍的题目均会用到二进制…

麒麟部署一套NFS服务器,用于创建网络文件系统

一、服务端共享目录 在本例中,kyserver01(172.16.200.10)作为客户端,创建一个目录/testdir并挂载共享目录;kyserver02(172.16.200.11)作为服务端,创建一个共享目录/test,设置为读写权限,要求客户端使用root登录时映射为nobody用户、非root登录时保持不变。 服务端启…

VBA技术资料MF228:移动形状并覆盖某单元格区域

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套&#xff0c;分为初级、中级、高级三大部分&#xff0c;教程是对VBA的系统讲解&#…

Python 数据分析核心库大全!

&#xff08;欢迎关注我的视频号&#xff09; &#x1f447;我的小册 45章教程:(小白零基础用Python量化股票分析小册) ,原价299&#xff0c;限时特价2杯咖啡&#xff0c;满100人涨10元。 大家好&#xff01;我是菜鸟哥&#xff01; 今天我们来聊点干货&#xff1a;Python 数据…

跨境出海安全:如何防止PayPal账户被风控?

今天咱们聊聊那些让人头疼的事儿——PayPal账户被风控。不少跨境电商商家反馈&#xff0c;我们只是想要安安静静地在网上做个小生意&#xff0c;结果不知道为什么&#xff0c;莫名其妙账户就被冻结了。 但其实每个封禁都是有原因的&#xff0c;今天就来给大家分享分享可能的原…

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

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

数据科学与SQL:组距分组分析 | 区间分布问题

目录 0 问题描述 1 数据准备 2 问题分析 3 小结 0 问题描述 绝对值分布分析也可以理解为组距分组分析。对于某个指标而言&#xff0c;一个记录对应的指标值的绝对值&#xff0c;肯定落在所有指标值的绝对值的最小值和最大值构成的区间内&#xff0c;根据一定的算法&#x…

使用 PyTorch-BigGraph 构建和部署大规模图嵌入的完整教程

当涉及到图数据时&#xff0c;复杂性是不可避免的。无论是社交网络中的庞大互联关系、像 Freebase 这样的知识图谱&#xff0c;还是推荐引擎中海量的数据量&#xff0c;处理如此规模的图数据都充满挑战。 尤其是当目标是生成能够准确捕捉这些关系本质的嵌入表示时&#xff0c;…

23种设计模式-模板方法(Template Method)设计模式

文章目录 一.什么是模板方法模式&#xff1f;二.模板方法模式的特点三.模板方法模式的结构四.模板方法模式的应用场景五.模板方法模式的优缺点六.模板方法模式的C实现七.模板方法模式的JAVA实现八.代码解析九.总结 类图&#xff1a; 模板方法设计模式类图 一.什么是模板方法模…

.net的winfrom程序 窗体透明打开窗体时出现在屏幕右上角

窗体透明&#xff0c; 将Form的属性Opacity&#xff0c;由默认的100% 调整到 80%(尽量别低于50%)&#xff0c;这个数字越小越透明&#xff01; 打开窗体时出现在屏幕右上角 //构造函数 public frmCalendarList() {InitializeComponent();//打开窗体&#xff0c;窗体出现在屏幕…

DRNN 神经网络的Jacobian 信息辨识

DRNN 神经网络的 Jacobian 信息辨识 1. 基本原理 Jacobian 矩阵用于描述多输入多输出系统中输入和输出之间的偏导关系&#xff0c;其形式为&#xff1a; 对于 DRNN&#xff08;Dynamic Recurrent Neural Network&#xff09;&#xff0c;其动态特性使得 y(t)\mathbf{y}(t)y(t…

iptables网络安全服务详细使用

iptables防火墙概念说明 开源的基于数据包过滤的网络安全策略控制工具。 centos6.9 --- 默认防火墙工具软件iptables centos7 --- 默认防火墙工具软件firewalld&#xff08;zone&#xff09; iptables主要工作在OSI七层的二、三、四层&#xff0c;如果重新编译内核&…

《DAMA 数据管理知识体系指南》读书笔记 - 第 2 章 数据处理伦理

文章目录 1. 章节概述2. 核心概念与定义3. 重要方法与实践步骤4. 理论与实际结合5. 重点6. 理解与记忆要点7. 复习思考题标题图——书籍图片 WPS AI生成的XMind链接&#xff08;不用要源文件&#xff0c;下载不了&#xff09;&#xff1a; 【金山文档 | WPS云文档】 第2章 数据…

《线性代数的本质》

之前收藏的一门课&#xff0c;刚好期末复习&#xff0c;顺便看一看哈哈 课程链接&#xff1a;【线性代数的本质】合集-转载于3Blue1Brown官方双语】 向量究竟是什么 线性代数中最基础、最根源的组成部分就是向量&#xff0c;需要先明白什么是向量 不同专业对向量的看法 物理专…

AI 大模型如何重塑软件开发流程?——技术革新与未来展望

人工智能的蓬勃发展为许多领域注入了强劲动力&#xff0c;而在软件开发这一关键技术领域&#xff0c;AI 大模型的应用正在彻底改变传统流程。从代码自动生成到智能测试&#xff0c;再到协同开发和流程优化&#xff0c;AI 正逐步成为软件开发者的得力助手&#xff0c;也推动企业…

三季度业绩亮点多元,宝尊全域经营走向破茧成蝶

电商行业的变革从未停止&#xff0c;始终反映着网络消费和品牌发展的趋势&#xff0c;以及未来的想象空间&#xff0c;因此令赛道上的相关公司备受关注。 那么&#xff0c;当前赛道正在发生哪些变化&#xff1f;11月21日&#xff0c;行业龙头宝尊电商发布截至2024年9月30日的2…

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

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

【云计算】腾讯云架构高级工程师认证TCP--考纲例题,知识点总结

【云计算】腾讯云架构高级工程师认证TCCP–知识点总结&#xff0c;排版整理 文章目录 1、云计算架构概论1.1 五大版块知识点&#xff08;架构设计&#xff0c;基础服务&#xff0c;高阶技术&#xff0c;安全&#xff0c;上云&#xff09;1.2 课程详细目录1.3 云基础架构设计1.4…

proto3语法详解

proto3语法详解 字段规则消息类型的定义与使⽤定义使用 enum类型定义与使用定义规则定义时注意事项 Any类型Any类型介绍Any类型使用 oneof类型oneof类型的介绍oneof类型的使用 map类型map类型的介绍map类型的使用 默认值更新消息更新规则保留字段reserved 未知字段未知字段获取…

【STM32】在 STM32 USB 设备库添加新的设备类

说实话&#xff0c;我非常想吐槽 STM32 的 USB device library&#xff0c;总感觉很混乱。 USB Device library architecture 根据架构图&#xff1a; Adding a custom class 如果你想添加新的设备类&#xff0c;必须修改的文件有 usbd_desc.cusbd_conf.cusb_device.c 需要…