题1 生命游戏

描述

根据 百度百科 ,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在 1970 年发明的细胞自动机。
给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞。每个细胞都具有一个初始状态:1 即为活细胞(live),或 0 即为死细胞(dead)。每个细胞与其八个相邻位置(水平,垂直,对角线)的细胞都遵循以下四条生存定律:
如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞死亡;
如果活细胞周围八个位置有两个或三个活细胞,则该位置活细胞仍然存活;
如果活细胞周围八个位置有超过三个活细胞,则该位置活细胞死亡;
如果死细胞周围正好有三个活细胞,则该位置死细胞复活;
根据当前状态,写一个函数来计算面板上所有细胞的下一个(一次更新后的)状态。下一个状态是通过将上述规则同时应用于当前状态下的每个细胞所形成的,其中细胞的出生和死亡是同时发生的
示例:
输入:
[
[0,1,0],
[0,0,1],
[1,1,1],
[0,0,0]
]
输出:
[
[0,0,0],
[1,0,1],
[0,1,1],
[0,1,0]
]
进阶:
你可以使用原地算法解决本题吗?请注意,面板上所有格子需要同时被更新:你不能先更新某些格子,然后使用它们的更新后的值再更新其他格子。
本题中,我们使用二维数组来表示面板。原则上,面板是无限的,但当活细胞侵占了面板边界时会造成问题。你将如何解决这些问题?

题解

这个题和之前的地图题很像,实现思路没有问题,但是实现的时候有问题。我第一个的问题出在把if判断写成了while导致超时,第二个的问题出在忘了要同步更新这个要求,各自必须同时更新,所以需要保留原始的格子的值。

法1:拷贝矩阵: 因为需要再创建一个二维矩阵保存原始数据所以内存消耗较大

执行用时 :1 ms, 在所有 Java 提交中击败了37.80%的用户
内存消耗 :38.2 MB, 在所有 Java 提交中击败了5.71%的用户

class Solution {public void gameOfLife(int[][] board) {int[] neighbors = {1,-1,0};int[][] copyBoard = new int[board.length][board[0].length];for(int i = 0; i < board.length; i++){for(int j = 0; j < board[0].length; j++){copyBoard[i][j] = board[i][j];}}for(int i = 0; i < board.length; i++){for(int j = 0; j < board[0].length; j++){int alive = 0;for(int a = 0; a < 3; a++){for(int b = 0; b < 3; b++){if(neighbors[a]!=0 || neighbors[b] != 0){int r = i+neighbors[a];int c = j+neighbors[b];if(r>=0&&r<board.length&&c>=0&&c<board[0].length&&copyBoard[r][c]==1){alive++;}}}}// 规则 1 或规则 3      if ((copyBoard[i][j]==1)&&(alive<2||alive>3)) {board[i][j] = 0;}// 规则 4if (copyBoard[i][j] == 0 && alive == 3) {board[i][j] = 1;}}}}
}

法2 定义复合状态法
空间复杂度为O(1) 时间复杂度同上O(mn)

根据数组的细胞状态计算新一轮的细胞状态,这里会用到能同时代表过去状态和现在状态的复合状态。
具体的计算规则如下所示:
规则 1:如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞死亡。这时候,将细胞值改为 -1,代表这个细胞过去是活的现在死了;
规则 2:如果活细胞周围八个位置有两个或三个活细胞,则该位置活细胞仍然存活。这时候不改变细胞的值,仍为 1;
规则 3:如果活细胞周围八个位置有超过三个活细胞,则该位置活细胞死亡。这时候,将细胞的值改为 -1,代表这个细胞过去是活的现在死了。可以看到,因为规则 1 和规则 3 下细胞的起始终止状态是一致的,因此它们的复合状态也一致;
规则 4:如果死细胞周围正好有三个活细胞,则该位置死细胞复活。这时候,将细胞的值改为 2,代表这个细胞过去是死的现在活了。

class Solution {public void gameOfLife(int[][] board) {int[] neighbors = {0, 1, -1};int rows = board.length;int cols = board[0].length;// 遍历面板每一个格子里的细胞for (int row = 0; row < rows; row++) {for (int col = 0; col < cols; col++) {// 对于每一个细胞统计其八个相邻位置里的活细胞数量int liveNeighbors = 0;for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {if (!(neighbors[i] == 0 && neighbors[j] == 0)) {// 相邻位置的坐标int r = (row + neighbors[i]);int c = (col + neighbors[j]);// 查看相邻的细胞是否是活细胞if ((r < rows && r >= 0) && (c < cols && c >= 0) && (Math.abs(board[r][c]) == 1)) {liveNeighbors += 1;}}}}// 规则 1 或规则 3 if ((board[row][col] == 1) && (liveNeighbors < 2 || liveNeighbors > 3)) {// -1 代表这个细胞过去是活的现在死了board[row][col] = -1;}// 规则 4if (board[row][col] == 0 && liveNeighbors == 3) {// 2 代表这个细胞过去是死的现在活了board[row][col] = 2;}}}// 遍历 board 得到一次更新后的状态for (int row = 0; row < rows; row++) {for (int col = 0; col < cols; col++) {if (board[row][col] > 0) {board[row][col] = 1;} else {board[row][col] = 0;}}}}
}

【LeetCode】4月2日打卡-Day18-矩阵操作相关推荐

  1. leetcode.cn 2022年11月4日 打卡题 754. 到达终点数字【一元二次方程解法,时间复杂度O(1)】

    leetcode 2022年11月4日 打卡题 754. 到达终点数字 写在前面   首先感谢 @子不语 大佬发布的一元二次方程代码实现的启发.题解链接:子不语-754. 到达终点数字   本文侧重梳 ...

  2. 2020年6月23日打卡

    打卡 2020年6月23日 计划与安排 Leetcode 67. 二进制求和 学习笔记 这位先生我能占用您一点时间吗-- 计划与安排 预期每天在博客中叙述如下内容: 每日做leetcode的感悟与题解 ...

  3. 3月19日 打卡

    一周第一次课(3月19日) 1.1 学习之初 1.2 约定 1.3 认识Linux 1.4 安装虚拟机 1.5 安装centos7 学习Liux 真的只是一场缘分,之前我只知道她是一个操作系统.但我重 ...

  4. 【LeetCode】3月17日打卡-Day2

    题1 拼写单词 描述 给你一份『词汇表』(字符串数组) words 和一张『字母表』(字符串) chars. 假如你可以用 chars 中的『字母』(字符)拼写出 words 中的某个『单词』(字符串 ...

  5. 【LeetCode】4月5日打卡-Day21-最大子序和问题

    描述 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和. 示例: 输入: [-2,1,-3,4,-1,2,1,-5,4], 输出: 6 解释: 连续 ...

  6. 【LeetCode】4月4日打卡-Day20-接雨水

    描述 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水. 上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下, ...

  7. 【LeetCode】4月3日打卡-Day19-字符串转整数

    描述 请你来实现一个 atoi 函数,使其能将字符串转换成整数. 首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止.接下来的转化规则如下: 如果第一个非空字符为正或者负号 ...

  8. 【LeetCode】4月1日打卡-Day17-括号匹配/嵌套深度

    题1 有效括号的嵌套深度 题解 要求划分出使得最大嵌套深度最小的分组,我们首先得知道如何计算嵌套深度.我们可以通过栈实现括号匹配来计算: 维护一个栈 s,从左至右遍历括号字符串中的每一个字符: 如果当 ...

  9. 【LeetCode】3月31日打卡-Day16-数组排序算法汇总

    排序算法一览 快排 插入排序 希尔排序 桶排序 计数排序 归并排序 桶排序 class Solution {public int[] sortArray(int[] nums) {if(nums.le ...

最新文章

  1. [platform]新旧内核的device设备注册对比
  2. java文件绝对路径_获取文件夹文件绝对路径
  3. Python 开发植物大战僵尸游戏
  4. 别傻了,你还认为 count(1) 比 count(*) 效率高?
  5. SUSE Linux维护笔记三
  6. C++编程基础二 13-函数与string对象
  7. 公众号 多服务器配置_多领国微信官方公众号在线
  8. 第五讲 C#中的异常处理
  9. maya 2017 linux 下载,Maya插件下载 Maya神级特效优化插件Soup For Maya 2017-2019 Win/Mac/Linux安装版 下载-脚本之家...
  10. “指定的网络名不再可用”解决办法
  11. python flask web框架_Python_WEB框架之Flask
  12. matlab生成word文档
  13. uni-app 快手小程序如何设置跟元素样式
  14. c语言中表明空格的是什么代码,C语言代码中的空白符表示什么
  15. #今日论文推荐# 莫纳什大学最新《长文档摘要》综述,39页pdf长文档摘要的实证研究:数据集、模型和指标
  16. Excel表格中输入一个姓,就可以选择输入需要的姓名了
  17. 西门子1200plc轴运动控制程序模板
  18. 杭州师范大学c语言程序设计机试,杭州师范大学C语言试题第3套.pdf
  19. C语言为什么不会过时
  20. 2019美和易思第十一期班主任选拔培训(贵州+重庆区域)拉开帷幕

热门文章

  1. clamav Java_ClamAV安装使用及API例子
  2. 和后台如何对接_业务系统如何对接第三方服务?
  3. python中sys模块有什么用_Python中模块之sys的功能介绍
  4. LeetCode MySQL 1132. 报告的记录 II
  5. LeetCode MySQL 1421. 净现值查询
  6. 程序员面试金典 - 面试题 16.07. 最大数值(位运算求max)
  7. android studio有错误,清单合并失败,Android Studio中出现多个错误
  8. collections求和方法_java集合求和最大值最小值示例分享
  9. 一台机器起多个filebeat_全自动多色丝印机一台多少钱?
  10. 代写python代码一般多少钱_代写CO 353课程作业、代做Python程序设计作业、代写Python语言作业...