题解 | #礼物的最大价值#
礼物的最大价值
https://www.nowcoder.com/practice/2237b401eb9347d282310fc1c3adb134
kotlin
动态规划基础版
object Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param grid int整型二维数组
* @return int整型
*/
fun maxValue(grid: Array<IntArray>): Int {
val record = Array<IntArray>(grid.size + 1) {
IntArray(grid[0].size + 1)
}
for(i in 1..grid.size) {
for(j in 1..grid[0].size) {
//因为只能向下或向右移动,所以当前的最大价值等于上面或者左边的值最大加上当前的值
record[i][j] = maxOf(record[i - 1][j], record[i][j - 1]) + grid[i - 1][ j - 1]
}
}
return record[grid.size][grid[0].size]
}
动态规划进阶版-滚动数组
object Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param grid int整型二维数组
* @return int整型
*/
fun maxValue(grid: Array<IntArray>): Int {
//注意到其实我们只用到上一个数组的值,即record[i - 1][j],所以维护两个一维数组即可
val record = IntArray(grid[0].size + 1)
val temp = IntArray(grid[0].size + 1)
for(i in 1..grid.size) {
for(j in 1..grid[0].size) {
temp[j] = maxOf(record[j], temp[j - 1]) + grid[i - 1][ j - 1]
}
System.arraycopy(temp, 0, record, 0, record.size)
}
return record[grid[0].size]
}
}
object Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param grid int整型二维数组
* @return int整型
*/
fun maxValue(grid: Array<IntArray>): Int {
//注意到我们其实只用了上一个数组的相同j的值(即record[i - 1][j]),使用滚动数组还是浪费空间的,我们可以只使用一个一维数组也是可以的
val record = IntArray(grid[0].size + 1)
for(i in 1..grid.size) {
for(j in 1..grid[0].size) {
//此时等号右边的record[j]相当于record[i - 1][j],因为此时的record[j]还没有被重新赋值,所以值还是等于record[i - 1][j],所以我们用一个数组即可
record[j] = maxOf(record[j], record[j - 1]) + grid[i - 1][ j - 1]
}
}
return record[grid[0].size]
}
}
深度搜索+记忆优化
object Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param grid int整型二维数组
* @return int整型
*/
fun maxValue(grid: Array<IntArray>): Int {
val record = Array<IntArray>(grid.size) {
IntArray(grid[0].size)
}
var max = 0
for(i in grid.indices) {
for(j in grid[0].indices) {
max = maxOf(max, dfs(grid, record, i, j))
}
}
return max
}
private fun dfs(grid: Array<IntArray>, record: Array<IntArray>, down: Int, right: Int): Int {
if(down == grid.size || right == grid[0].size) return 0
//已经计算过直接返回结果
if(record[down][right] > 0) return record[down][right]
//一个点只能向下或向右移动所以 一个点的最大值计算过后他就不会再改变,所以我们可以先计算所有还没有计算过的点的最大值
var sum = grid[down][right]
sum += maxOf(dfs(grid, record, down + 1, right), dfs(grid, record, down, right + 1))
record[down][right] = sum
return sum
}
}