博客
关于我
1594 矩阵的最大非负积(动态规划)
阅读量:365 次
发布时间:2019-03-04

本文共 3426 字,大约阅读时间需要 11 分钟。

1. 问题描述:

给你一个大小为 rows x cols 的矩阵 grid 。最初,你位于左上角 (0, 0) ,每一步,你可以在矩阵中向右或向下移动。

在从左上角 (0, 0) 开始到右下角 (rows - 1, cols - 1) 结束的所有路径中,找出具有 最大非负积 的路径。路径的积是沿路径访问的单元格中所有整数的乘积。
返回最大非负积对10 ^ 9 + 7 取余 的结果。如果最大积为负数,则返回 -1 。
注意,取余是在得到最大积之后执行的。

示例 1:

输入:grid = [[-1,-2,-3],

             [-2,-3,-3],
             [-3,-3,-2]]
输出:-1
解释:从 (0, 0) 到 (2, 2) 的路径中无法得到非负积,所以返回 -1

示例 2:

输入:grid = [[1,-2,1],

             [1,-2,1],
             [3,-4,1]]
输出:8
解释:最大非负积对应的路径已经用粗体标出 (1 * 1 * -2 * -4 * 1 = 8)

示例 3:

输入:grid = [[1, 3],

             [0,-4]]
输出:0
解释:最大非负积对应的路径已经用粗体标出 (1 * 0 * -4 = 0)

示例 4:

输入:grid = [[ 1, 4,4,0],

             [-2, 0,0,1],
             [ 1,-1,1,1]]
输出:2
解释:最大非负积对应的路径已经用粗体标出 (1 * -2 * 1 * -1 * 1 * 1 = 2)

提示:

  • 1 <= rows, cols <= 15
  • -4 <= grid[i][j] <= 4

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/maximum-non-negative-product-in-a-matrix

2. 思路分析:

① 因为求解的是二维矩阵中的关于路径的问题,所以一开始想到的是递归的思路去解决,尝试搜索二维矩阵中的所有路径并且在递归方法中传入一个int类型变量来记录这些路径的最大值,当递归的位置到grid[row][col]的时候那么更新历史上路径最大值,但是使用python提交上去超时了

② 除了使用递归尝试所有的路径的乘积的方法之外,还可以使用动态规划的思路去解决,并且使用动态规划的思路也比较容易想到,我们使用两个二维列表来记录到达当前位置的最大值与最小值,这样每次到达当前位置的时候可以使用dp列表的左边与上边的位置对应的值乘以当前grid列表对应的值,这样就求解出到达当前位置的最小值与最大值了,为什么要记录当前位置的最小值呢:因为二维矩阵中是存在负数的情况的,当前面一条路径的乘积为负数的时候而且到达当前grid列表的位置对应的也为负数的时候那么这个时候这条路径的乘积是正数,所以这就构成了到达当前位置的正数乘积了,最后我们需要判断到达grid列表的最后一个位置的时候乘积是正数还是负数来决定返回值的情况

③ 这道题目与之前:乘积最大子数组的是类似的

3. 代码如下:

动态规划代码:

from typing import Listclass Solution:    def maxProductPath(self, grid: List[List[int]]) -> int:        # 其实这道题目使用动态规划是最简单的依次计算能够到达当前位置的最大选择        r, c = len(grid), len(grid[0])        # 初始化二维列表dp        dp1 = [[0] * c for i in range(r)]        dp2 = [[0] * c for i in range(r)]        # 初始化第一列        dp1[0][0] = dp2[0][0] = grid[0][0]        for i in range(1, r):            dp1[i][0] = dp1[i - 1][0] * grid[i][0]            dp2[i][0] = dp2[i - 1][0] * grid[i][0]        # 初始化第一行        for i in range(1, c):            dp1[0][i] = dp1[0][i - 1] * grid[0][i]            dp2[0][i] = dp2[0][i - 1] * grid[0][i]        for i in range(1, r):            for j in range(1, c):                dp1[i][j] = max(dp1[i - 1][j] * grid[i][j], dp1[i][j - 1] * grid[i][j], dp2[i - 1][j] * grid[i][j], dp2[i][j - 1] * grid[i][j])                dp2[i][j] = min(dp1[i - 1][j] * grid[i][j], dp1[i][j - 1] * grid[i][j], dp2[i - 1][j] * grid[i][j], dp2[i][j - 1] * grid[i][j])        return dp1[r - 1][c - 1] % (10 ** 9 + 7) if dp1[r - 1][c - 1] >= 0 else -1

超时的递归代码:

import sysfrom typing import Listclass Solution:    res = -sys.maxsize    def dfs(self, grid: List[List[int]], x: int, y: int, r: int, c: int, pos: List[List[int]], mul: int):        if x == r and y == c:            if self.res < mul:                self.res = max(self.res, mul)            return        # 剪枝假如乘积为0那么不再递归下去        if mul == 0: return         for cur in pos:            tx = x + cur[0]            ty = y + cur[1]            if 0 <= tx <= r and 0 <= ty <= c:                t = grid[tx][ty]                if t != -sys.maxsize:                    grid[tx][ty] = -sys.maxsize                    self.dfs(grid, tx, ty, r, c, pos, mul * t)                    # 回溯                    grid[tx][ty] = t    def maxProductPath(self, grid: List[List[int]]) -> int:        pos = [[1, 0], [0, 1]]        t = grid[0][0]        grid[0][0] = -sys.maxsize        rec = list()        rec.append(t)        self.dfs(grid, 0, 0, len(grid) - 1, len(grid[0]) - 1, pos, t)        for i in grid:            if 0 in i and self.res < 0:                return 0        return self.res % (10 ** 9 + 7) if self.res >= 0 else -1

 

转载地址:http://nmgr.baihongyu.com/

你可能感兴趣的文章
MySQL中interactive_timeout和wait_timeout的区别
查看>>
mysql中int、bigint、smallint 和 tinyint的区别、char和varchar的区别详细介绍
查看>>
mysql中json_extract的使用方法
查看>>
mysql中json_extract的使用方法
查看>>
mysql中kill掉所有锁表的进程
查看>>
mysql中like % %模糊查询
查看>>
MySql中mvcc学习记录
查看>>
mysql中null和空字符串的区别与问题!
查看>>
MySQL中ON DUPLICATE KEY UPDATE的介绍与使用、批量更新、存在即更新不存在则插入
查看>>
MYSQL中TINYINT的取值范围
查看>>
MySQL中UPDATE语句的神奇技巧,让你操作数据库如虎添翼!
查看>>
Mysql中varchar类型数字排序不对踩坑记录
查看>>
MySQL中一条SQL语句到底是如何执行的呢?
查看>>
MySQL中你必须知道的10件事,1.5万字!
查看>>
MySQL中使用IN()查询到底走不走索引?
查看>>
Mysql中使用存储过程插入decimal和时间数据递增的模拟数据
查看>>
MySql中关于geometry类型的数据_空的时候如何插入处理_需用null_空字符串插入会报错_Cannot get geometry object from dat---MySql工作笔记003
查看>>
mysql中出现Incorrect DECIMAL value: '0' for column '' at row -1错误解决方案
查看>>
mysql中出现Unit mysql.service could not be found 的解决方法
查看>>
mysql中出现update-alternatives: 错误: 候选项路径 /etc/mysql/mysql.cnf 不存在 dpkg: 处理软件包 mysql-server-8.0的解决方法(全)
查看>>