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

相关文章

JavaScript对象转数组的三种方法实现

《JavaScript对象转数组的三种方法实现》本文介绍了在JavaScript中将对象转换为数组的三种实用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友... 目录方法1:使用Object.keys()和Array.map()方法2:使用Object.entr

JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法

《JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法》:本文主要介绍JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法,每种方法结合实例代码给大家介绍的非常... 目录引言:为什么"相等"判断如此重要?方法1:使用some()+includes()(适合小数组)方法2

基于Python实现数字限制在指定范围内的五种方式

《基于Python实现数字限制在指定范围内的五种方式》在编程中,数字范围限制是常见需求,无论是游戏开发中的角色属性值、金融计算中的利率调整,还是传感器数据处理中的异常值过滤,都需要将数字控制在合理范围... 目录引言一、基础条件判断法二、数学运算巧解法三、装饰器模式法四、自定义类封装法五、NumPy数组处理

Java中数组与栈和堆之间的关系说明

《Java中数组与栈和堆之间的关系说明》文章讲解了Java数组的初始化方式、内存存储机制、引用传递特性及遍历、排序、拷贝技巧,强调引用数据类型方法调用时形参可能修改实参,但需注意引用指向单一对象的特性... 目录Java中数组与栈和堆的关系遍历数组接下来是一些编程小技巧总结Java中数组与栈和堆的关系关于

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数组排序