前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >剑指OfferV2(增) -- 礼物的最大价值

剑指OfferV2(增) -- 礼物的最大价值

作者头像
秦怀杂货店
发布2022-02-15 15:01:57
1910
发布2022-02-15 15:01:57
举报
文章被收录于专栏:技术杂货店

Part0前言

剑指Offer & LeetCode刷题仓库https://github.com/Damaer/CodeSolution 文档地址https://damaer.github.io/CodeSolution/ 刷题仓库介绍刷题仓库:CodeSolution 编程知识库https://github.com/Damaer/Coding 文档地址https://damaer.github.io/Coding/#/ 剑指OfferV1 系列已经完成,补增 V2 题目以及C++语言解法,欢迎关注~

Part147.礼物的最大价值

1题目描述

在一个m × n的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?

如输入这样的一个二维数组,

代码语言:javascript
复制
[
[1,3,1],
[1,5,1],
[4,2,1]
]

那么路径 1→3→5→2→1 可以拿到最多价值的礼物,价值为12

示例1

代码语言:javascript
复制
输入:[[1,3,1],[1,5,1],[4,2,1]]
返回值:12

2思路 & 解答

这道题其实一看就知道是动态规划,棋盘中的每个小格子,都是和上方,或者左方的格子有关。既然是动态规划,那么我们先定义状态:

dp[i][j]]: 从(0,0)到(i,j)所能拿到的礼物的最大价值

定义好状态之后,需要找出状态转移方程,也就是如何从前面的结果中,推导到现在的结果,在这道题中,只能向右或者向下,那么假设当前格子的礼物是gift[i][j],当前的最大价值dp[i][j]Max(dp[i-1][j]+gift[i][j],dp[i][j-1]+gift[i][j])

当然如果是第一行和第一列,其实是边界情况,不需要处理,dp[i][j] = gift[i][j]

总结一下:

但是我们可以直接在原数组上操作,不用新建dp数组。Java代码实现如下:

代码语言:javascript
复制
public class Solution47 {
    public int maxValue(int[][] gifts) {
        int n = gifts.length, m = gifts[0].length;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                int x = gifts[i][j];
                if (i - 1 >= 0) {
                    gifts[i][j] = Math.max(gifts[i][j], x + gifts[i - 1][j]);
                }
                if (j - 1 >= 0) {
                    gifts[i][j] = Math.max(gifts[i][j], x + gifts[i][j - 1]);
                }
            }
        }
        return gifts[n - 1][m - 1];
    }
}

c++代码如下:

代码语言:javascript
复制
class Solution {
public:
    int maxValue(vector<vector<int> >& gifts) {
        int n = gifts.size(), m = gifts[0].size();
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                int x = gifts[i][j];
                if (i - 1 >= 0) {
                    gifts[i][j] = max(gifts[i][j], x + gifts[i - 1][j]);
                }
                if (j - 1 >= 0) {
                    gifts[i][j] = max(gifts[i][j], x + gifts[i][j - 1]);
                }
            }
        }
        return gifts[n - 1][m - 1];
    }
};
  • 时间复杂度:O(nm),需要计算完里面的小格子
  • 空间复杂度:O(1),优化后可以实现原地操作,不需要额外的空间

【作者简介】

秦怀,公众号【秦怀杂货店】作者,技术之路不在一时,山高水长,纵使缓慢,驰而不息。个人写作方向:Java源码解析,JDBC,Mybatis,Spring,Redis,分布式,剑指Offer,LeetCode等,认真写好每一篇文章,不喜欢标题党,不喜欢花里胡哨,大多写系列文章,不能保证我写的都完全正确,但是我保证所写的均经过实践或者查找资料。遗漏或者错误之处,还望指正。

平日时间宝贵,只能使用晚上以及周末时间学习写作

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-01-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 秦怀杂货店 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Part0前言
  • Part147.礼物的最大价值
    • 1题目描述
      • 2思路 & 解答
      相关产品与服务
      云数据库 Redis®
      腾讯云数据库 Redis®(TencentDB for Redis®)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档