每日一题 - 剑指 Offer 47. 礼物的最大价值
题目信息
时间: 2019-07-02
题目链接:Leetcode
tag:动态规划
难易程度:中等
题目描述:
在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?
示例:
输入:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
输出: 12
解释: 路径 1→3→5→2→1 可以拿到最多价值的礼物
注意
1. 0 < grid.length <= 200
2. 0 < grid[0].length <= 200
解题思路
本题难点
根据题目说明,某单元格可能从上边单元格或左边单元格到达。
具体思路
动态规划解决此问题,转移方程f(i,j)=max[f(i,j−1),f(i−1,j)]+grid(i,j)
设动态规划矩阵 dp(i,j) 代表从棋盘的左上角开始,到达单元格 (i,j) 时能拿到礼物的最大累计价值。
- 当 i = 0 且 j = 0时,起始元素。
- 当 i = 0 且 j != 0时,为矩阵第一行元素,只可从左边到达;
- 当 i != 0 且 j = 0时,为矩阵第一列元素,只可从上边到达;
- 当 i != 0 且 j != 0时,可从左边或上边到达;
注意:由于 dp[i] [j] 只与 dp[i−1] [j] , dp[i] [j−1] , grid[ i ] [ j ]有关系,因此可以将原矩阵 grid 用作 dp 矩阵,即直接在 grid 上修改即可。
代码
class Solution {
public int maxValue(int[][] grid) {
int m = grid.length, n = grid[0].length;
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
// dp[0][0]=grid[0][0]
if(i == 0 && j == 0) continue;
if(i == 0) grid[i][j] += grid[i][j - 1] ;
else if(j == 0) grid[i][j] += grid[i - 1][j];
else grid[i][j] += Math.max(grid[i][j - 1], grid[i - 1][j]);
}
}
//dp[m−1][n−1] ,m,n 分别为矩阵的行高和列宽,即返回 dp 矩阵右下角元素
return grid[m - 1][n - 1];
}
}
复杂度分析:
- 时间复杂度 O(MN) : M,N分别为矩阵行高、列宽;动态规划需遍历整个 grid 矩阵。
- 空间复杂度 O(1) : 原地修改使用常数大小的额外空间。
其他优秀解答
解题思路
多开辟一个二维数组的空间,节省边界值的判断。
代码
class Solution {
public int maxValue(int[][] grid) {
int row = grid.length;
int col = grid[0].length;
int[][] dp = new int[row+1][col+1];
for(int i = 1;i <= row;i++){
for(int j = 1; j <= col; j++){
dp[i][j] = Math.max(dp[i-1][j],dp[i][j-1]) + grid[i-1][j-1];
}
}
return dp[row][col];
}
}
每日一题 - 剑指 Offer 47. 礼物的最大价值的更多相关文章
- 力扣 - 剑指 Offer 47. 礼物的最大价值
题目 剑指 Offer 47. 礼物的最大价值 思路1 因为是要求最大价值,而且只能移动下方或者右方,因此,每个位置的最大值就是本身的值加上上边 / 左边 中的最大值,然后每次遍历都可以复用上一次的值 ...
- 【Java】 剑指offer(47) 礼物的最大价值
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 在一个m×n的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值( ...
- 剑指 Offer 47. 礼物的最大价值
题目描述 在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0).你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格.直到到达棋盘的右下角.给定一个棋盘及 ...
- 每日一题 - 剑指 Offer 49. 丑数
题目信息 时间: 2019-07-03 题目链接:Leetcode tag:动态规划 小根堆 难易程度:中等 题目描述: 我们把只包含质因子 2.3 和 5 的数称作丑数(Ugly Number).求 ...
- 每日一题 - 剑指 Offer 45. 把数组排成最小的数
题目信息 时间: 2019-07-01 题目链接:Leetcode tag: 快速排序 难易程度:中等 题目描述: 输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最 ...
- 每日一题 - 剑指 Offer 40. 最小的k个数
题目信息 时间: 2019-06-30 题目链接:Leetcode tag: 快排 难易程度:中等 题目描述: 输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3. ...
- 每日一题 - 剑指 Offer 53 - I. 在排序数组中查找数字 I
题目信息 时间: 2019-07-04 题目链接:Leetcode tag:二分查找 哈希表 难易程度:简单 题目描述: 统计一个数字在排序数组中出现的次数. 示例1: 输入: nums = [5,7 ...
- 每日一题 - 剑指 Offer 52. 两个链表的第一个公共节点
题目信息 时间: 2019-07-03 题目链接:Leetcode tag: 单链表 难易程度:简单 题目描述: 输入两个链表,找出它们的第一个公共节点. 示例: A: a1 -> a2 \ - ...
- 每日一题 - 剑指 Offer 50. 第一个只出现一次的字符
题目信息 时间: 2019-07-03 题目链接:Leetcode tag:哈希表 难易程度:简单 题目描述: 在字符串 s 中找出第一个只出现一次的字符.如果没有,返回一个单空格. s 只包含小写字 ...
随机推荐
- java实现砝码称重
5个砝码 用天平称重时,我们希望用尽可能少的砝码组合称出尽可能多的重量. 如果只有5个砝码,重量分别是1,3,9,27,81.则它们可以组合称出1到121之间任意整数重量(砝码允许放在左右两个盘中). ...
- java实现滑动解锁
滑动解锁是智能手机一项常用的功能.你需要在3x3的点阵上,从任意一个点开始,反复移动到一个尚未经过的"相邻"的点.这些划过的点所组成的有向折线,如果与预设的折线在图案.方向上都一致 ...
- Java实现 蓝桥杯 算法提高 道路和航路
问题描述 农夫约翰正在针对一个新区域的牛奶配送合同进行研究.他打算分发牛奶到T个城镇(标号为1-T),这些城镇通过R条标号为(1-R)的道路和P条标号为(1-P)的航路相连. 每一条公路i或者航路i表 ...
- 基本的bash shell 命令
1.遍历目录:cd 2.显示目录列表:ls 3.创建文件:touch 4.复制文件:cp 5.链接文件:ln 6.重命名文件:mv 7.删除文件:rm 8.创建目录:mkdir 9.删除目录:rmdi ...
- OAuth + Security - 5 - Token存储升级(数据库、Redis)
PS:此文章为系列文章,建议从第一篇开始阅读. 在我们之前的文章中,我们当时获取到Token令牌时,此时的令牌时存储在内存中的,这样显然不利于我们程序的扩展,所以为了解决这个问题,官方给我们还提供了其 ...
- chattr +i 用户也没法随意删除
root用户也没法用rm随意删除文件? 前言 在你的印象中,是不是root用户就可以为所欲为呢?随便一个rm -rf *,一波骚操作走人?可能没那么容易. 先来个示例,创建一个文本文件test.t ...
- ElasticSearch6.3脚本更新
使用上篇文章创建的索引进行学习:https://www.cnblogs.com/wangymd/p/11200996.html 官方文档:https://www.elastic.co/guide/en ...
- kernel list 实践
list.h /******* 链表实现,来自内核 **************************************************/ /** * container_of - c ...
- grafana 如何对数据进行切分
也就是如何增加筛选,根据想要的条件筛选不同的内容,数据源是prometheus 效果 设置variable 正则表达式 匹配url中IP和端口 切片进阶 根据前一个切片 再过滤 含义说明 instan ...
- 分享一个springboot脚手架
项目介绍 在我们开发项目的时候各个项目之间总有一些可共用的代码或者配置,如果我们每新建一个项目就把代码复制粘贴再修改就显得很没有必要.于是我就做了一个 poseidon-boot-starter 该项 ...