个人理解所谓动态规划类似于数学中的归纳演绎,根据小部分数据(n=1,2,3...)开始推测计算公式。
本文提供一种递归方式计算硬币问题的解决方式。
计算公式:d(i) = min(d(i-coin)+1) coin-币值
package com.xxx.test;
import java.util.Arrays;
/**
* @author :aoyeye
* @date :Created in 2019/3/21 11:18
* @description:
* @modified By:
*/
public class TestList {
public static void main(String[] args) {
System.out.println(a_fun(21));
}
private static int a_fun(int num) {
int[] coins = {1, 3, 5};
int sum = num;
if (num == 0) {
return 0;
}
for (int coin : coins) {
if (coin == num) {
return 1;
}
if (num > coin) {
sum = Math.min(a_fun(num - coin) + 1, sum);
}
}
return sum;
}
}
类似场景矩阵最短路径计算:
/**
* 输入:
* [
* [1,3,1],
* [1,5,1],
* [4,2,1]
* ]
* 输出: 7
* 解释: 因为路径 1→3→1→1→1 的总和最小
* 说明:每次只能向下或者向右移动一步
* m = grid.length
* n = grid[0].length
*/
private static int calculate(int m, int n, int[][] grid) {
int result = 0;
if (m == 1) {
for (int i = 0; i < n; i++) {
result += grid[0][i];
}
return result;
}
if (n == 1) {
for (int i = 0; i < m; i++) {
result += grid[i][0];
}
return result;
}
result = Math.min(calculate(m - 1, n, grid), calculate(m, n - 1, grid)) + grid[m - 1][n - 1];
return result;
}
leetcode上使用递归方式解决提示超时,因此看了网友提供的直接循环遍历,将每一步结果都存入sum[][]中,整体思想一致
public static int minPathSum(int[][] grid) {
int[][] sum = new int[grid.length][grid[0].length];
sum[0][0] = grid[0][0];
for (int i = 1; i < grid[0].length; i++) {
sum[0][i] = sum[0][i - 1] + grid[0][i];
}
for (int j = 1; j < grid.length; j++) {
sum[j][0] = sum[j - 1][0] + grid[j][0];
}
for (int i = 1; i < grid.length; i++) {
for (int j = 1; j < grid[0].length; j++) {
sum[i][j] = Math.min(sum[i - 1][j], sum[i][j - 1]) + grid[i][j];
}
}
return sum[grid.length - 1][grid[0].length - 1];
// 递归方式解决,超时
// int m = grid.length;
// if (m == 0) {
// return 0;
// }
// int n = grid[0].length;
// if (n == 0) {
// return 0;
// }
// return calculate(m, n, grid);
}
网友评论