谷歌(Google)历年编程真题——生命游戏

news2024/11/24 21:03:40

谷歌历年面试真题——数组和字符串系列真题练习。

生命游戏

根据 百度百科 , 生命游戏 ,简称为 生命 ,是英国数学家约翰·何顿·康威在 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] 为 0 或 1

思路一:模拟细胞状态转换

  1. 遍历整个网格面板,对于每个细胞,计算其周围的活细胞数量。
  2. 根据题目给出的生存定律,更新每个细胞的状态:
    • 如果一个活细胞周围的活细胞数量少于两个或多于三个,则该细胞死亡。
    • 如果一个死细胞周围有三个活细胞,则该细胞复活。
    • 其他情况下,细胞的状态不变。
  3. 将更新后的网格返回作为下一个状态。

下面是相应的 Python 代码实现:

def gameOfLife(board):
    m, n = len(board), len(board[0])
    directions = [(1, 0), (-1, 0), (0, 1), (0, -1), (1, 1), (-1, -1), (1, -1), (-1, 1)]
    
    # 获取周围活细胞数量
    def countLiveNeighbors(row, col):
        count = 0
        for dx, dy in directions:
            x, y = row + dx, col + dy
            if 0 <= x < m and 0 <= y < n and (board[x][y] == 1 or board[x][y] == -1):
                count += 1
        return count
    
    # 更新细胞状态
    for i in range(m):
        for j in range(n):
            live_neighbors = countLiveNeighbors(i, j)
            if board[i][j] == 1 and (live_neighbors < 2 or live_neighbors > 3):
                board[i][j] = -1  # 表示活细胞死亡
            if board[i][j] == 0 and live_neighbors == 3:
                board[i][j] = 2   # 表示死细胞复活
    
    # 更新细胞状态
    for i in range(m):
        for j in range(n):
            if board[i][j] == -1:
                board[i][j] = 0
            elif board[i][j] == 2:
                board[i][j] = 1
    
    return board

# 示例 1
board1 = [[0,1,0],[0,0,1],[1,1,1],[0,0,0]]
print(gameOfLife(board1))  # 输出:[[0,0,0],[1,0,1],[0,1,1],[0,1,0]]

# 示例 2
board2 = [[1,1],[1,0]]
print(gameOfLife(board2))  # 输出:[[1,1],[1,1]]

这个函数实现了生命游戏的状态转换逻辑,并返回下一个状态的网格面板。

思路二:使用额外标记实现状态转换

除了模拟细胞状态转换的方法外,还可以通过使用额外的标记来实现状态转换,而不对原始网格进行修改。具体思路如下:

  1. 遍历整个网格面板,对于每个细胞,计算其周围的活细胞数量。
  2. 根据题目给出的生存定律,不修改原始网格,而是使用额外的标记表示下一个状态:
    • 如果一个活细胞周围的活细胞数量少于两个或多于三个,则该细胞在下一个状态为死亡,标记为 -1。
    • 如果一个死细胞周围有三个活细胞,则该细胞在下一个状态为活细胞,标记为 2。
    • 其他情况下,细胞的状态不变,标记为原始状态。
  3. 根据标记更新网格,返回下一个状态的网格。

下面是相应的 Python 代码实现:

def gameOfLife(board):
    m, n = len(board), len(board[0])
    directions = [(1, 0), (-1, 0), (0, 1), (0, -1), (1, 1), (-1, -1), (1, -1), (-1, 1)]
    
    # 获取周围活细胞数量
    def countLiveNeighbors(row, col):
        count = 0
        for dx, dy in directions:
            x, y = row + dx, col + dy
            if 0 <= x < m and 0 <= y < n and (board[x][y] == 1 or board[x][y] == -1):
                count += 1
        return count
    
    # 根据生存定律标记下一个状态
    for i in range(m):
        for j in range(n):
            live_neighbors = countLiveNeighbors(i, j)
            if board[i][j] == 1 and (live_neighbors < 2 or live_neighbors > 3):
                board[i][j] = -1  # 表示活细胞死亡
            if board[i][j] == 0 and live_neighbors == 3:
                board[i][j] = 2   # 表示死细胞复活
    
    # 更新网格状态
    for i in range(m):
        for j in range(n):
            if board[i][j] == -1:
                board[i][j] = 0
            elif board[i][j] == 2:
                board[i][j] = 1
    
    return board

# 示例 1
board1 = [[0,1,0],[0,0,1],[1,1,1],[0,0,0]]
print(gameOfLife(board1))  # 输出:[[0,0,0],[1,0,1],[0,1,1],[0,1,0]]

# 示例 2
board2 = [[1,1],[1,0]]
print(gameOfLife(board2))  # 输出:[[1,1],[1,1]]

这个解法避免了直接修改原始网格,而是通过标记的方式表示下一个状态,然后再根据标记更新网格。

思路三:状态压缩

除了模拟细胞状态转换和使用额外标记的方法外,还可以使用状态压缩的方法解决这个问题。状态压缩是一种优化技巧,用于减少空间复杂度。

  1. 遍历整个网格面板,对于每个细胞,计算其周围的活细胞数量。
  2. 根据题目给出的生存定律,根据当前细胞的状态和周围的活细胞数量,计算出下一个状态的细胞状态。
  3. 使用额外的状态表示方法,将下一个状态的细胞状态编码到一个二进制数中,这样就可以使用一个二进制数来表示整个网格面板的下一个状态。
  4. 根据编码后的状态生成新的网格面板。

下面是相应的 Python 代码实现:

def gameOfLife(board):
    m, n = len(board), len(board[0])
    directions = [(1, 0), (-1, 0), (0, 1), (0, -1), (1, 1), (-1, -1), (1, -1), (-1, 1)]
    
    # 获取周围活细胞数量
    def countLiveNeighbors(row, col):
        count = 0
        for dx, dy in directions:
            x, y = row + dx, col + dy
            if 0 <= x < m and 0 <= y < n and (board[x][y] == 1 or board[x][y] == -1):
                count += 1
        return count
    
    # 计算下一个状态的细胞状态并编码
    for i in range(m):
        for j in range(n):
            live_neighbors = countLiveNeighbors(i, j)
            if board[i][j] == 1 and (live_neighbors < 2 or live_neighbors > 3):
                board[i][j] = 2  # 表示当前细胞死亡,下一个状态仍为死亡
            if board[i][j] == 0 and live_neighbors == 3:
                board[i][j] = -1  # 表示当前细胞复活,下一个状态为活细胞
    
    # 解码并更新网格状态
    for i in range(m):
        for j in range(n):
            if board[i][j] == 2:
                board[i][j] = 0
            elif board[i][j] == -1:
                board[i][j] = 1
    
    return board

# 示例 1
board1 = [[0,1,0],[0,0,1],[1,1,1],[0,0,0]]
print(gameOfLife(board1))  # 输出:[[0,0,0],[1,0,1],[0,1,1],[0,1,0]]

# 示例 2
board2 = [[1,1],[1,0]]
print(gameOfLife(board2))  # 输出:[[1,1],[1,1]]

这个解法通过状态压缩的方式,用一个二进制数表示整个网格面板的下一个状态,从而减少了空间复杂度。

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

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

相关文章

Python 全栈体系【四阶】(二十五)

第五章 深度学习 三、计算机视觉基本理论 11. 图像梯度处理 11.1 什么是图像梯度 图像梯度计算的是图像变化的速度。对于图像的边缘部分&#xff0c;其灰度值变化较大&#xff0c;梯度值也较大&#xff1b;相反&#xff0c;对于图像中比较平滑的部分&#xff0c;其灰度值变化…

蓝桥杯复习笔记

文章目录 gridflexhtml表格合并单元格 表单表单元素input类型 select h5文件上传拖拽apiweb Storage css块元素和行内元素转换positionfloat溢出显示隐藏外边距过渡和动画动画变形选择器属性选择伪类选择器 css3边框圆角边框阴影渐变text-overflow与word-wrap jsdom操作documen…

一键下载安装并自动绑定,Xinstall让您的应用推广更高效

在如今的移动互联网时代&#xff0c;应用的下载安装与绑定是用户体验的关键一环。然而&#xff0c;繁琐的操作步骤和复杂的绑定流程往往让用户望而却步&#xff0c;降低了应用的下载和使用率。为了解决这一难题&#xff0c;Xinstall应运而生&#xff0c;为用户提供了一种全新的…

gradio简单搭建——关键词匹配筛选

gradio简单搭建——关键词匹配筛选 界面搭建数据处理过程执行效果展示 上一节使用DataFrame中的apply方法提升了表格数据的筛选效率&#xff0c;本节使用gradio结合apply方法搭建一个关键词匹配筛选的交互界面。 界面搭建 import gradio as gr import pandas as pd from file…

C语言指针—二级指针和指针数组

二级指针和指针数组 二级指针 指针变量也是变量&#xff0c;是变量就有地址&#xff0c;那指针变量的地址存放在哪里&#xff1f; 这就是二级指针 。 int main() {int a 10;int* pa &a;//pa是一个指针变量&#xff0c;同时也是一个一级指针变量*pa 20;//此时解引用pa…

021——搭建TCP网络通信环境(c服务器python客户端)

目录 前言 服务器程序 服务器程序验证过程 客户端程序 前言 驱动开发暂时告一段落了。后面在研究一下OLED和GPS的驱动开发&#xff0c;并且优化前面已经移植过来的这些驱动&#xff0c;我的理念是在封装个逻辑处理层来处理这些驱动程序。server直接操作逻辑处理层的程序。 …

统信UOS(Linux)安装nvm node管理工具

整篇看完再操作&#xff0c;有坑&#xff01;&#xff01; 官网 nvm官网 按照官网方式安装&#xff0c;一直报 错 经过不断研究&#xff0c;正确步骤如下 1、下载安装包 可能因为网络安全不能访问github&#xff0c;我是链接热点下载的 wget https://github.com/nvm-sh/…

基于springboot+vue+Mysql的职称评审管理系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

Mac安装配置ElasticSearch和Kibana 8.13.2

系统环境&#xff1a;Mac M1 (MacOS Sonoma 14.3.1) 一、准备 从Elasticsearch&#xff1a;官方分布式搜索和分析引擎 | Elastic上下载ElasticSearch和Kibana 笔者下载的是 elasticsearch-8.13.2-darwin-aarch64.tar.gz kibana-8.13.2-darwin-aarch64.tar.gz 并放置到个人…

序列化、反序列化:将对象以字节流的方式,进行写入或读取

序列化&#xff1a;将指定对象&#xff0c;以"字节流"的方式写入一个文件或网络中。 反序列化&#xff1a;从一个文件或网络中&#xff0c;以"字节流"的方式读取到对象。 package com.ztt.Demo01;import java.io.FileNotFoundException; import java.io.Fi…

C++的stack和queue类(一):适配器模式、双端队列与优先级队列

目录 基本概念 适配器模式 stack.h test.cpp 双端队列-deque 仿函数 优先级队列 基本概念 1、stack和queue不是容器是容器适配器&#xff0c;它们没有迭代器 2、stack的quque的默认容器是deque&#xff0c;因为&#xff1a; stack和queue不需要遍历&#xff0…

基于SSM+Jsp+Mysql的农产品供销服务系统

开发语言&#xff1a;Java框架&#xff1a;ssm技术&#xff1a;JSPJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包…

0基础想进入IT行业,可以从这个框架入手

行业现状 IT、AI都是很多年来的热门话题&#xff0c;以至于时至今日&#xff0c;哪怕IT行业已经卷成狗&#xff0c;依然有无数的人想要挤进这个行业。 大模型、云原生、react等等&#xff0c;无数的技术、概念应运而生。那么作为一个没有基础的人&#xff0c;该如何进入这个行…

第十四届蓝桥杯模拟考试II_物联网设计

还是要稳妥啊&#xff0c;写A板的时候感觉很简单所以将模块都混在一起了&#xff0c;结果不出意外就出BUG了又得从头开始查BUG,多简单的题模块最好都分块写写完就检查&#xff0c;这样一步一个脚印多稳 这个模块出了俩BUG第一个是要检查有没有数据进入if语句&#xff0c;不然标…

Kubernetes(k8s)监控与报警(qq邮箱+钉钉):Prometheus + Grafana + Alertmanager(超详细)

Kubernetes&#xff08;k8s&#xff09;监控与报警&#xff08;qq邮箱钉钉&#xff09;&#xff1a;Prometheus Grafana Alertmanager&#xff08;超详细&#xff09; 1、部署环境2、基本概念简介2.1、Prometheus简介2.2、Grafana简介2.3、Alertmanager简介2.4、Prometheus …

OpenCV | 图像读取与显示

OpenCV 对图像进行处理时&#xff0c;常用API如下&#xff1a; API描述cv.imread根据给定的磁盘路径加载对应的图像&#xff0c;默认使用BGR方式加载cv.imshow展示图像cv.imwrite将图像保存到磁盘中cv.waitKey暂停一段时间&#xff0c;接受键盘输出后&#xff0c;继续执行程序…

力扣面试150 分发糖果 分步贪心

Problem: 135. 分发糖果 思路 &#x1f468;‍&#x1f3eb; 参考&#xff1a;代码随想录 一次是从左到右遍历&#xff0c;只比较右边孩子评分比左边大的情况。一次是从右到左遍历&#xff0c;只比较左边孩子评分比右边大的情况。 复杂度 时间复杂度: O ( n ) O(n) O(n) …

代码随想录算法训练营第三十六天| LeetCode 435. 无重叠区间、763.划分字母区间、56. 合并区间

一、LeetCode 435. 无重叠区间 题目链接/文章讲解/视频讲解&#xff1a;https://programmercarl.com/0435.%E6%97%A0%E9%87%8D%E5%8F%A0%E5%8C%BA%E9%97%B4.html 状态&#xff1a;已解决 1.思路 本题的局部最优是尽量移除与某个区间重叠的其他区间&#xff0c;全局最优是移除的…

构建强健身体的未来:健身管理平台微服务架构解析

在现代社会&#xff0c;人们越来越关注健康和身体素质的提升。健身管理平台应运而生&#xff0c;为用户提供个性化的健身计划、监测和管理工具。微服务架构作为一种灵活且可扩展的系统设计方法&#xff0c;为健身管理平台提供了高效、可靠的基础。 1. 概述健身管理平台微服务架…

Open CASCADE学习|统计形状拓扑数量

边界表示法&#xff08;Boundary Representation&#xff0c;简称B-Rep&#xff09;是几何造型中最成熟、无二义的表示法。它主要用于描述物体的几何信息和拓扑信息。在边界表示法中&#xff0c;一个实体&#xff08;Solid&#xff09;由一组封闭的面&#xff08;Face&#xff…