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

相关文章

Java中的数组与集合基本用法详解

《Java中的数组与集合基本用法详解》本文介绍了Java数组和集合框架的基础知识,数组部分涵盖了一维、二维及多维数组的声明、初始化、访问与遍历方法,以及Arrays类的常用操作,对Java数组与集合相... 目录一、Java数组基础1.1 数组结构概述1.2 一维数组1.2.1 声明与初始化1.2.2 访问

MySQL查询JSON数组字段包含特定字符串的方法

《MySQL查询JSON数组字段包含特定字符串的方法》在MySQL数据库中,当某个字段存储的是JSON数组,需要查询数组中包含特定字符串的记录时传统的LIKE语句无法直接使用,下面小编就为大家介绍两种... 目录问题背景解决方案对比1. 精确匹配方案(推荐)2. 模糊匹配方案参数化查询示例使用场景建议性能优

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方

苹果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