题目链接

下降路径最小和II

题目描述

image.png

实现代码

个人实现代码,未AC,还在找原因:

  1. class Solution {
  2. public int minFallingPathSum(int[][] matrix) {
  3. int m = matrix.length;
  4. int n = matrix[0].length;
  5. int[][] dp = new int[m][n];
  6. int preRowMin = Integer.MAX_VALUE;
  7. int preRowNextMin = Integer.MAX_VALUE;
  8. int preRowMinJ = 0;
  9. for(int j=0; j<n; j++) {
  10. dp[0][j] = matrix[0][j];
  11. if(dp[0][j] < preRowMin) {
  12. preRowMin = dp[0][j];
  13. preRowMinJ = j;
  14. } else if(dp[0][j] < preRowNextMin) {
  15. preRowNextMin = dp[0][j];
  16. }
  17. }
  18. if(m == 1) {
  19. return preRowMin;
  20. }
  21. for(int i=1; i<m; i++) {
  22. int tempRowMin = Integer.MAX_VALUE;
  23. int tempRowNextMin = Integer.MAX_VALUE;
  24. int tempRowMinJ = 0;
  25. for(int j=0; j<n; j++) {
  26. if(j == preRowMinJ) {
  27. dp[i][j] = preRowNextMin + matrix[i][j];
  28. } else {
  29. dp[i][j] = preRowMin + matrix[i][j];
  30. }
  31. if(tempRowMin > dp[i][j]) {
  32. tempRowMin = dp[i][j];
  33. tempRowMinJ = j;
  34. } else if(tempRowNextMin > dp[i][j]) {
  35. tempRowNextMin = dp[i][j];
  36. }
  37. }
  38. preRowMin = tempRowMin;
  39. preRowMinJ = tempRowMinJ;
  40. preRowNextMin = tempRowNextMin;
  41. }
  42. return preRowMin;
  43. }
  44. }

copy别人的代码,已AC:

  1. class Solution {
  2. int MAX = Integer.MAX_VALUE;
  3. public int minFallingPathSum(int[][] arr) {
  4. int n = arr.length;
  5. int[][] f = new int[n][n];
  6. // i1 代表最小值列下标,i2 代表次小值列下标
  7. int i1 = -1, i2 = -1;
  8. // 先转移第一行
  9. for (int i = 0; i < n; i++) {
  10. // 更新动规值
  11. int val = arr[0][i];
  12. f[0][i] = val;
  13. // 更新 i1 和 i2
  14. if (val < (i1 == -1 ? MAX : f[0][i1])) {
  15. i2 = i1;
  16. i1 = i;
  17. } else if (val < (i2 == -1 ? MAX : f[0][i2])) {
  18. i2 = i;
  19. }
  20. }
  21. // 再转移剩余行
  22. for (int i = 1; i < n; i++) {
  23. // 当前转移第 i 行,使用临时变量保存转移过程中的「最小值列下标」&「次小值列下标」
  24. int ti1 = -1, ti2 = -1;
  25. for (int j = 0; j < n; j++) {
  26. f[i][j] = MAX;
  27. int val = arr[i][j];
  28. // 更新动规值
  29. // 可以选择「最小值」的列选择「最小值」
  30. if (j != i1) {
  31. f[i][j] = f[i - 1][i1] + val;
  32. // 不能选择「最小值」的列选择「次小值」
  33. } else {
  34. f[i][j] = f[i - 1][i2] + val;
  35. }
  36. // 更新 ti1 和 ti2
  37. if (f[i][j] < (ti1 == -1 ? MAX : f[i][ti1])) {
  38. ti2 = ti1;
  39. ti1 = j;
  40. } else if (f[i][j] < (ti2 == -1 ? MAX : f[i][ti2])) {
  41. ti2 = j;
  42. }
  43. }
  44. // 使用临时变量更新 i1 和 i2
  45. i1 = ti1; i2 = ti2;
  46. }
  47. int ans = Integer.MAX_VALUE;
  48. for (int i = 0; i < n; i++) {
  49. ans = Math.min(ans, f[n-1][i]);
  50. }
  51. return ans;
  52. }
  53. }