动态规划<第 2 天>

x33g5p2x  于2021-12-07 转载在 其他  
字(1.5k)|赞(0)|评价(0)|浏览(358)

三角矩阵

思路:
动规题目,我们需要分析出状态,状态转移方程,初始状态和返回结果

  • 方式① 自上向下解决

代码实现:

  1. public int minTotal(ArrayList<ArrayList<Integer>> triangle){
  2. if(triangle.isEmpty()){
  3. return 0;
  4. }
  5. List<List<Integer>> min = new ArrayList<>();
  6. for(int i = 0; i < triangle.size(); ++i) {
  7. min.add(new ArrayList<>());
  8. }
  9. // F[0][0]初始化
  10. min.get(0).add(triangle.get(0).get(0));
  11. for(int i = 1; i < triangle.size(); ++i) {
  12. int curSum = 0;
  13. for(int j = 0; j <= i; ++j) {
  14. // 左边界
  15. if(j == 0) {
  16. curSum = min.get(i - 1).get(0);
  17. }
  18. // 右边界
  19. else if(j == i){
  20. curSum = min.get(i - 1).get(j - 1);
  21. }
  22. else{
  23. curSum = Math.min(min.get(i - 1).get(j),
  24. min.get(i - 1).get(j - 1));
  25. }
  26. // F(i,k) = min( F(i-1, k-1), F(i-1, k)) + triangle[i][k]
  27. min.get(i).add(triangle.get(i).get(j) + curSum);
  28. }
  29. }
  30. int size = triangle.size();
  31. // min(F(n-1, i))
  32. int minResult = min.get(size - 1).get(0);
  33. for(int i = 1; i < size; ++i) {
  34. minResult = Math.min(minResult,min.get(size - 1).get(i));
  35. }
  36. return minResult;
  37. }

方式① 的问题是,新增一个数组min[ ] 来保存当前层到下一层各个节点最短的路径值,但是由于获得下一层结点的最短路径时,当前数组的各个值会用到两次,那么就不可能在计算下一层的最短结点的时候逐个覆盖当前数组的值,因此需要再增加一个数组,来交替存储最新的最短路径值,但这样就不满足 O(N) 的空间复杂度

  • 方式② 自下向上解决

代码实现:

  1. public int minimumTotal(ArrayList<ArrayList<Integer>> triangle) {
  2. if (triangle.isEmpty()){
  3. return 0;
  4. }
  5. //记录三角形的层数
  6. int row = triangle.size();
  7. //创建一个暂存数组,用于存放到达每一层各个节点的最小步数
  8. int[] temp = new int[row];
  9. //先初始化temp数组,暂存最后一层的结点
  10. for (int i = 0; i < row; i++)
  11. temp[i] = triangle.get(row-1).get(i);
  12. //然后向上运算,到达上一层的最小值,应该是当前层的结点,也就是暂存数组的元素两两比较的最小值和上一层结点的相加
  13. for(int i = row - 2; i >= 0; i--){
  14. for(int k = 0; k <= i; k++){
  15. temp[k] = triangle.get(i).get(k) + Math.min(temp[k],temp[k + 1]);
  16. }
  17. }
  18. return temp[0];
  19. }

方式② 需要用到额外的一个数组,temp[n],O(N) 的空间复杂度,当计算到达上一层的最短路径并覆盖存储到 temp[n] 数组时,覆盖的那个节点已经不需要再次使用了,所以不需要再新增一个数组

相关文章