剑指offer||礼物的最大价值

108 阅读1分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

一、题目描述

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

示例 1:

输入: [ [1,3,1], [1,5,1], [4,2,1] ] 输出: 12 解释: 路径 1→3→5→2→1 可以拿到最多价值的礼物

提示:

0 < grid.length <= 200 0 < grid[0].length <= 200

二、思路分析

  1. 首先考虑到使用回溯算法,全局变量为max
  2. 如果 i<0或者j<0,超出下界,或者 i==n,j == m 超出上界,返回
  3. 礼物价值为加上当前遍历到的价值,如果当前价值和大于max则更改max值,调用回溯向下和向右继续遍历,回溯时将val减去当前礼物值。

三、AC 代码

func maxValue(grid [][]int) int {
    n,m := len(grid),len(grid[0])
    max := 0
    var  dfs func (i,j,val int) 
    dfs = func (i,j,val int){
        if i < 0 || j < 0  || i >= n || j >= m {
            return
        }
        val+= grid[i][j]
        if val > max {
            max = val
        }
        dfs(i,j+1,val)
        dfs(i+1,j,val)
        val -= grid[i][j]
    }
    dfs(0,0,0)
    return max

}

四、总结

使用回溯方式可以很简易的求解出max值,考虑到暴力遍历对时间复杂度的影响,可以进行记忆化递归,开启一个记忆矩阵,将值记录在记忆矩阵中,如果走到该位置,可直接返回值,减少递归次数。