(矩阵) 289. 生命游戏 ——【Leetcode每日一题】

news2025/1/18 16:56:28

❓ 289. 生命游戏

难度:中等

根据 百度百科 , 生命游戏 ,简称为 生命 ,是英国数学家约翰·何顿·康威在 1970 年发明的细胞自动机。

给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞。每个细胞都具有一个初始状态: 1 即为 活细胞 (live),或 0 即为 死细胞 (dead)。每个细胞与其八个相邻位置(水平,垂直,对角线)的细胞都遵循以下四条生存定律:

  1. 如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞死亡;
  2. 如果活细胞周围八个位置有两个三个活细胞,则该位置活细胞仍然存活;
  3. 如果活细胞周围八个位置有超过三个活细胞,则该位置活细胞死亡;
  4. 如果死细胞周围正好有三个活细胞,则该位置死细胞复活;

下一个状态是通过将上述规则同时应用于当前状态下的每个细胞所形成的,其中细胞的出生和死亡是同时发生的。给你 m x n 网格面板 board 的当前状态,返回下一个状态。

示例 1:

在这里插入图片描述

输入:board = [[0,1,0],[0,0,1],[1,1,1],[0,0,0]]
输出:[[0,0,0],[1,0,1],[0,1,1],[0,1,0]]

示例 2:

在这里插入图片描述

输入:board = [[1,1],[1,0]]
输出:[[1,1],[1,1]]

提示

  • m == board.length
  • n == board[i].length
  • 1 <= m, n <= 25
  • board[i][j]01

进阶

  • 你可以使用原地算法解决本题吗?请注意,面板上所有格子需要同时被更新:你不能先更新某些格子,然后使用它们的更新后的值再更新其他格子。
  • 本题中,我们使用二维数组来表示面板。原则上,面板是无限的,但当活细胞侵占了面板边界时会造成问题。你将如何解决这些问题?

💡思路:(位运算,原地解决)

由题意细胞的出生和死亡是同时发生的,所以当前时刻的所有状态都要被保存,在不使用额外空间的情况下,可以使用原数组进行保存,原数组 只是用了一位来记录细胞状态,所以我们可以使用 高一位 来记录下一刻所有细胞的状态。

规则总结p 细胞周围8个位置(中的不越界部分)存在

  • 1、小于2个或多余3个活细胞1时,p下一状态必然是死细胞 0
  • 2、当 p 周围有2个时,p不变,周围有3个 1 时,若 p0 则复活变为 1,若 p1 则不变。

额外临时数组记录变更后状态,遍历结束后给原数组重新赋值。

位运算状态存储技巧:原数组值仅有 10 ,那么可以用二进制高一位存储其变更后的状态;
每个点 p 在作为周边位置参与统计 1 时使用最低位数字,p 作为中心点时根据统计结果得到的下一步状态存储在最高位(第二位)

🍁代码:(C++、Java)

C++

class Solution {
public:
    int dir[8][2] = {{-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}};
    void gameOfLife(vector<vector<int>>& board) {
        int m = board.size(), n = board[0].size();
        for(int i = 0; i < m; ++i){
            for(int j = 0; j < n; ++j){
                int cnt = 0;
                for(int k = 0; k < 8; ++k){
                    int row = i + dir[k][0], col = j + dir[k][1];
                    if(row >= 0 && row < m && col >= 0 && col < n && (board[row][col] & 1) == 1){
                        ++cnt;
                    }
                }
                if(cnt == 3){
                    board[i][j] |= (1 << 1);
                }else if(cnt == 2){
                    board[i][j] |= (board[i][j] << 1);
                }
            }
        }
        for(int i = 0; i < m; ++i){
            for(int j = 0; j < n; ++j){
                board[i][j] >>= 1;
            }
        }
    }
};

Java

class Solution {
    int [][] dir = {{-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}};
    public void gameOfLife(int[][] board) {
        int m = board.length, n = board[0].length;
        for(int i = 0; i < m; ++i){
            for(int j = 0; j < n; ++j){
                int cnt = 0;
                for(int k = 0; k < 8; ++k){
                    int row = i + dir[k][0], col = j + dir[k][1];
                    if(row >= 0 && row < m && col >= 0 && col < n && (board[row][col] & 1) == 1){
                        ++cnt;
                    }
                }
                if(cnt == 3){
                    board[i][j] |= (1 << 1);
                }else if(cnt == 2){
                    board[i][j] |= (board[i][j] << 1);
                }
            }
        }
        for(int i = 0; i < m; ++i){
            for(int j = 0; j < n; ++j){
                board[i][j] >>= 1;
            }
        }
    }
}
🚀 运行结果:

在这里插入图片描述

🕔 复杂度分析:
  • 时间复杂度 O ( m n ) O(mn) O(mn),其中mn 分别为 board 的行数和列数。
  • 空间复杂度 O ( 1 ) O(1) O(1),除原数组外只需要常数的空间存放若干变量。

题目来源:力扣。

放弃一件事很容易,每天能坚持一件事一定很酷,一起每日一题吧!
关注我LeetCode主页 / CSDN—力扣专栏,每日更新!

注: 如有不足,欢迎指正!

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

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

相关文章

【算法设计与分析qwl】伪码——顺序检索,插入排序

伪代码&#xff1a; 例子&#xff1a; 改进的顺序检索 Search(L,x)输入&#xff1a;数组L[1...n]&#xff0c;元素从小到大排序&#xff0c;数x输出&#xff1a;若x在L中&#xff0c;输出x位置下标 j ,否则输出0 j <- 1 while j<n and x>L[j] do j <- j1 if x<…

2022年全网最全最细最流行的自动化测试工具有哪些?

一&#xff1a;前言 随着测试工程师技能和工资待遇的提升&#xff0c;甚至有一部分的开发人员开始转入测试岗位&#xff0c;跨入自动化领域的测试攻城狮越来越多。在自动化测试领域&#xff0c;自动化工具肯定占据了核心的位置。 本文总结了常用的测试自动化工具和框架&#x…

QT_day2

使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 将登录按钮使用qt5版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin"&#xff0c;密码是否为…

rust学习——函数返回值

概念 Rust 中的函数定义以 fn 开始&#xff0c;后跟着函数名和一对圆括号。大括号告诉编译器函数体在哪里开始和结束。 特殊的地方——函数返回值 错误的写法 正解1 去掉分号 fn main() {let x plus_one(5);println!("The value of x is: {}", x); }fn plus_…

c++_learning-进阶部分

文章目录 类&#xff1a;抽象类&#xff1a;类、类作用域&#xff1a;类成员访问权限&#xff1a;使用细节&#xff1a;成员函数的修饰符const、mutable&#xff1a;const在类中的使用&#xff1a;mutable&#xff1a; this&#xff1a;返回自身对象的引用构造函数&#xff08;…

思科 Packet Tracer实验(一)

思科 Packet Tracer实验&#xff08;一&#xff09; ​ Cisco Packet Tracer 是由Cisco公司发布的一个辅助学习工具&#xff0c;为学习思科网络课程的初学者去设计、配置、排除网络故障提供了网络模拟环境。用户可以在软件的图形用户界面上直接使用拖曳方法建立网络拓扑&#…

金山终端安全系统V9.0 SQL注入漏洞复现

0x01 产品简介 金山终端安全系统是一款为企业提供终端防护的安全产品&#xff0c;针对恶意软件、病毒和外部攻击提供防范措施&#xff0c;帮助维护企业数据和网络。 0x02 漏洞概述 金山终端安全系统V9.0 /inter/update_software_info_v2.php页面存在sql注入漏洞&#xff0c;该…

李彦宏:我们即将进入一个AI原生的时代|百度世界2023

“大模型带来的智能涌现&#xff0c;这是我们开发AI原生应用的基础。” 10月17日&#xff0c;李彦宏在百度世界2023上表示。当天&#xff0c;李彦宏以《手把手教你做AI原生应用》为主题发表演讲&#xff0c;发布文心大模型4.0版本&#xff0c;并带来新搜索、新地图等十余款AI原…

时间序列预测 Graph-WaveNet:Graph WaveNet for Deep Spatial-Temporal Graph Modeling

Graph-WaveNet Graph WaveNet for Deep Spatial-Temporal Graph Modeling1.概述2.提出问题 & 解决策略 & 模型结构3.实验结果 ** Graph WaveNet for Deep Spatial-Temporal Graph Modeling ** 1.概述 时空图建模是分析系统中各组成部分的空间关系和时间趋势的一项重…

从裸机启动开始运行一个C++程序(十)

前序文章请看&#xff1a; 从裸机启动开始运行一个C程序&#xff08;九&#xff09; 从裸机启动开始运行一个C程序&#xff08;八&#xff09; 从裸机启动开始运行一个C程序&#xff08;七&#xff09; 从裸机启动开始运行一个C程序&#xff08;六&#xff09; 从裸机启动开始运…

算法基础学习|二分

二分 模板 整数二分模板 bool check(int x) {/* ... */} // 检查x是否满足某种性质// 区间[l, r]被划分成[l, mid]和[mid 1, r]时使用&#xff08;即寻找左边界使用&#xff09;&#xff1a; int bsearch_1(int l, int r) {while (l < r){int mid l r >> 1;if (…

最新AI创作系统ChatGPT源码+搭建部署教程+支持GPT4.0+支持ai绘画(Midjourney)/支持Prompt

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统AI绘画系统&#xff0c;支持OpenAI GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署…

Cocos Creator3.8 项目实战(十)使用 protobuf详细教程

在 Cocos Creator 中使用 protobuf.js 库可以方便地进行协议的序列化和反序列化。 下面是使用 protobuf.js 的详细说明&#xff1a; 一、protobuf环境安装 1、安装 npm protobuf环境安装安装需要使用 npm 命令进行&#xff0c;因此首先需要安装 npm 。 如果你还没安装 npm …

编程小白的自学笔记十六(python办公自动化操作EXCEL表格)

系列文章目录 编程小白的自学笔记十五&#xff08;python办公自动化操作EXCEL表格&#xff09; 编程小白的自学笔记十四&#xff08;python办公自动化创建、复制、移动文件和文件夹 编程小白的自学笔记十三&#xff08;python办公自动化读写文件&#xff09; 编程小白的自学…

网页下拉菜单

<!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>菜鸟教程(runoob.com)</title> </head> <body><form action""> <select name"cars"> <option value"vol…

【论文阅读】点云地图动态障碍物去除基准 A Dynamic Points Removal Benchmark in Point Cloud Maps

【论文阅读】点云地图动态障碍物去除基准 A Dynamic Points Removal Benchmark in Point Cloud Maps 终于一次轮到了讲自己的paper了 hahaha&#xff0c;写个中文的解读放在博客方便大家讨论 Title Picture Reference and prenotes paper: https://arxiv.org/abs/2307.07260 …

Win10+MX350+CUDA10.2+Python3.9配置Detectron2

配置步骤: 1. 创建一个新的虚拟环境 `conda create -n 2pcnet python=3.9`(事先安装好Anaconda3) 2. 激活并进入环境: `activate new_env` 3. 安装CUDA 查看电脑显卡型号:控制面板-管理工具-计算机管理-设备管理器-显示适配器(我的是MX350) 确定显卡支持的CUDA版…

【linux】基础IO+系统文件IO+文件描述符分配规则

基础IO系统文件IO文件描述符文件描述符分配规则 1.重新谈论文件2.重谈文件操作&#xff08;C语言&#xff09;2.1C文件接口 3.系统文件IO3.1open3.2close3.3write3.4read3.5lseek3.6总结 4.如何理解文件5.文件描述符&#xff08;fd&#xff09;分配规则 自我名言&#xff1a;只…

【LeetCode刷题(数据结构与算法)】:数据结构中的常用排序实现数组的升序排列

现在我先将各大排序的动图和思路以及代码呈现给大家 插入排序 直接插入排序是一种简单的插入排序法&#xff0c;其基本思想是&#xff1a; 把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中&#xff0c;直到所有的记录插入完为 止&#xff0c;得到一个…

“第四十三天”

这个是我自己写的&#xff0c;下面那个是看的别人的&#xff0c;其实大致都是一样的&#xff0c;通过四次循环&#xff0c;挨个求和比较&#xff0c;都很麻烦&#xff0c;但重点在于&#xff0c;对于已知变量的运用&#xff0c;当我需要在最内层循环用变量确定a数组组元时&…