2023-03-26:给定一个二维数组matrix, 每个格子都是正数,每个格子都和上、下、左、右相邻。 你可以从任何一个格子出发,走向相邻的格子, 把沿途的数字乘起来,希望得到的最终数字中,结尾的0

本文主要是介绍2023-03-26:给定一个二维数组matrix, 每个格子都是正数,每个格子都和上、下、左、右相邻。 你可以从任何一个格子出发,走向相邻的格子, 把沿途的数字乘起来,希望得到的最终数字中,结尾的0,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

2023-03-26:给定一个二维数组matrix,
每个格子都是正数,每个格子都和上、下、左、右相邻。
你可以从任何一个格子出发,走向相邻的格子,
把沿途的数字乘起来,希望得到的最终数字中,结尾的0最多,
走的过程中,向左走或者向右走的拐点,最多只能有一次。
返回结尾最多的0,能是多少。
1 <= 行、列 <= 400。

答案2023-03-26:

解题思路

本题需要求出从任意位置出发,最多能有多少个结尾0。为了方便计算,可以先将矩阵中每个数分解成2和5的因子,然后通过前缀和预处理出每个位置上、左方向的2和5的因子数量之和,以便快速计算6个方向上的因子数量之和。接着遍历每个位置,分别计算6个方向上的因子数量之和,并取其中的最小值,最后返回所有最小值中的最大值即可。

具体来说,对于一个位置(i,j),可以计算它的左、右、上、下4个方向的2和5的因子数量之和,以及两个斜方向的2和5的因子数量之和共6个值。然后取这6个值中的最小值,就是从该位置出发,在该方向上能够得到的最多结尾0的数量。遍历所有位置,取最大值即可。

需要注意的是,由于只能有一次向左或向右的拐点,因此在计算左和右方向上的因子数量之和时,需要分别计算到该行左边界和右边界的因子数量之和,然后再通过减法计算出中间部分的因子数量之和。

时间复杂度

本算法需要对矩阵中每个数进行分解质因数,时间复杂度为O(n ^ 2log(max(matrix)));两层循环分别对n和m进行遍历,时间复杂度为O(nm);因此总时间复杂度为O(n^2log(max(matrix))+nm)。

空间复杂度

本算法需要维护4个二维数组,每个数组的大小均为n×m,因此空间复杂度为O(nm)。

rust代码

fn most_trailing_zeros(matrix: &Vec<Vec<i32>>) -> i32 {let n = matrix.len(); // 矩阵行数let m = matrix[0].len(); // 矩阵列数// f2[i][j] : matrix[i][j]自己有几个2的因子let mut f2 = vec![vec![0; m]; n];// f5[i][j] : matrix[i][j]自己有几个5的因子let mut f5 = vec![vec![0; m]; n];// 预处理每个位置的2和5的因子数量for i in 0..n {for j in 0..m {f2[i][j] = factors(matrix[i][j], 2);f5[i][j] = factors(matrix[i][j], 5);}}// 计算每个位置上、左方向的2和5的因子数量之和let mut left_f2 = vec![vec![0; m]; n];let mut left_f5 = vec![vec![0; m]; n];let mut up_f2 = vec![vec![0; m]; n];let mut up_f5 = vec![vec![0; m]; n];for i in 0..n {for j in 0..m {left_f2[i][j] = f2[i][j] + if j > 0 { left_f2[i][j - 1] } else { 0 };left_f5[i][j] = f5[i][j] + if j > 0 { left_f5[i][j - 1] } else { 0 };up_f2[i][j] = f2[i][j] + if i > 0 { up_f2[i - 1][j] } else { 0 };up_f5[i][j] = f5[i][j] + if i > 0 { up_f5[i - 1][j] } else { 0 };}}let mut ans = 0;for i in 0..n {for j in 0..m {// 来到(i,j),计算6个方向上的因子数量之和let l2 = if j == 0 { 0 } else { left_f2[i][j - 1] }; // 左边的2因子数量之和 let l5 = if j == 0 { 0 } else { left_f5[i][j - 1] }; // 左边的5因子数量之和let r2 = left_f2[i][m - 1] - left_f2[i][j]; // 右边的2因子数量之和let r5 = left_f5[i][m - 1] - left_f5[i][j]; // 右边的5因子数量之和let u2 = if i == 0 { 0 } else { up_f2[i - 1][j] }; // 上面的2因子数量之和let u5 = if i == 0 { 0 } else { up_f5[i - 1][j] }; // 上面的5因子数量之和let d2 = up_f2[n - 1][j] - up_f2[i][j]; // 下面的2因子数量之和let d5 = up_f5[n - 1][j] - up_f5[i][j]; // 下面的5因子数量之和// 计算6个方向上因子数量之和最小的值let p1 = std::cmp::min(l2 + u2 + f2[i][j], l5 + u5 + f5[i][j]);let p2 = std::cmp::min(l2 + r2 + f2[i][j], l5 + r5 + f5[i][j]);let p3 = std::cmp::min(l2 + d2 + f2[i][j], l5 + d5 + f5[i][j]);let p4 = std::cmp::min(u2 + r2 + f2[i][j], u5 + r5 + f5[i][j]);let p5 = std::cmp::min(u2 + d2 + f2[i][j], u5 + d5 + f5[i][j]);let p6 = std::cmp::min(r2 + d2 + f2[i][j], r5 + d5 + f5[i][j]);// 取6个方向上的最小值中的最大值作为答案ans = std::cmp::max(ans,std::cmp::max(std::cmp::max(p1, p2),std::cmp::max(std::cmp::max(p3, p4), std::cmp::max(p5, p6)),),);}}ans
}// 计算num有几个f的因子
fn factors(num: i32, f: i32) -> i32 {let mut ans = 0;let mut num = num;while num % f == 0 {ans += 1;num /= f;}ans
}fn main() {let matrix1 = vec![vec![5, 8, 3, 1],vec![4, 15, 12, 1],vec![6, 7, 10, 1],vec![9, 1, 2, 1],];println!("{}", most_trailing_zeros(&matrix1)); // 输出:2let matrix2 = vec![vec![7500, 10, 11, 12],vec![6250, 13, 14, 15],vec![134, 17, 16, 1],vec![5500, 2093, 5120, 238],];println!("{}", most_trailing_zeros(&matrix2)); // 输出:13
}

运行结果

在这里插入图片描述

这篇关于2023-03-26:给定一个二维数组matrix, 每个格子都是正数,每个格子都和上、下、左、右相邻。 你可以从任何一个格子出发,走向相邻的格子, 把沿途的数字乘起来,希望得到的最终数字中,结尾的0的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/832252

相关文章

苹果macOS 26 Tahoe主题功能大升级:可定制图标/高亮文本/文件夹颜色

《苹果macOS26Tahoe主题功能大升级:可定制图标/高亮文本/文件夹颜色》在整体系统设计方面,macOS26采用了全新的玻璃质感视觉风格,应用于Dock栏、应用图标以及桌面小部件等多个界面... 科技媒体 MACRumors 昨日(6 月 13 日)发布博文,报道称在 macOS 26 Tahoe 中

MySQL JSON 查询中的对象与数组技巧及查询示例

《MySQLJSON查询中的对象与数组技巧及查询示例》MySQL中JSON对象和JSON数组查询的详细介绍及带有WHERE条件的查询示例,本文给大家介绍的非常详细,mysqljson查询示例相关知... 目录jsON 对象查询1. JSON_CONTAINS2. JSON_EXTRACT3. JSON_TA

JAVA数组中五种常见排序方法整理汇总

《JAVA数组中五种常见排序方法整理汇总》本文给大家分享五种常用的Java数组排序方法整理,每种方法结合示例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录前言:法一:Arrays.sort()法二:冒泡排序法三:选择排序法四:反转排序法五:直接插入排序前言:几种常用的Java数组排序

Linux搭建单机MySQL8.0.26版本的操作方法

《Linux搭建单机MySQL8.0.26版本的操作方法》:本文主要介绍Linux搭建单机MySQL8.0.26版本的操作方法,本文通过图文并茂的形式给大家讲解的非常详细,感兴趣的朋友一起看看吧... 目录概述环境信息数据库服务安装步骤下载前置依赖服务下载方式一:进入官网下载,并上传到宿主机中,适合离线环境

Python实现特殊字符判断并去掉非字母和数字的特殊字符

《Python实现特殊字符判断并去掉非字母和数字的特殊字符》在Python中,可以通过多种方法来判断字符串中是否包含非字母、数字的特殊字符,并将这些特殊字符去掉,本文为大家整理了一些常用的,希望对大家... 目录1. 使用正则表达式判断字符串中是否包含特殊字符去掉字符串中的特殊字符2. 使用 str.isa

Java数组初始化的五种方式

《Java数组初始化的五种方式》数组是Java中最基础且常用的数据结构之一,其初始化方式多样且各具特点,本文详细讲解Java数组初始化的五种方式,分析其适用场景、优劣势对比及注意事项,帮助避免常见陷阱... 目录1. 静态初始化:简洁但固定代码示例核心特点适用场景注意事项2. 动态初始化:灵活但需手动管理代

C++中初始化二维数组的几种常见方法

《C++中初始化二维数组的几种常见方法》本文详细介绍了在C++中初始化二维数组的不同方式,包括静态初始化、循环、全部为零、部分初始化、std::array和std::vector,以及std::vec... 目录1. 静态初始化2. 使用循环初始化3. 全部初始化为零4. 部分初始化5. 使用 std::a

shell编程之函数与数组的使用详解

《shell编程之函数与数组的使用详解》:本文主要介绍shell编程之函数与数组的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录shell函数函数的用法俩个数求和系统资源监控并报警函数函数变量的作用范围函数的参数递归函数shell数组获取数组的长度读取某下的

使用PyTorch实现手写数字识别功能

《使用PyTorch实现手写数字识别功能》在人工智能的世界里,计算机视觉是最具魅力的领域之一,通过PyTorch这一强大的深度学习框架,我们将在经典的MNIST数据集上,见证一个神经网络从零开始学会识... 目录当计算机学会“看”数字搭建开发环境MNIST数据集解析1. 认识手写数字数据库2. 数据预处理的

java字符串数字补齐位数详解

《java字符串数字补齐位数详解》:本文主要介绍java字符串数字补齐位数,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java字符串数字补齐位数一、使用String.format()方法二、Apache Commons Lang库方法三、Java 11+的St