1. 程式人生 > >Leetcode 120. Triangle--給定一個三角形,同頂部到底部的路徑數字之和的最小值,可以移動到下層相鄰的兩個元素

Leetcode 120. Triangle--給定一個三角形,同頂部到底部的路徑數字之和的最小值,可以移動到下層相鄰的兩個元素

Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.

For example, given the following triangle

[
     [2],
    [3,4],
   [6,5,7],
  [4,1,8,3]
]

The minimum path sum from top to bottom is 11 (i.e., 2 + 3

 + 5 + 1 = 11).

import java.util.ArrayList;
import java.util.List;

public class Leetcode_120_Triangle_DP1 {


    public static void main(String[] args) {
//[
//[2],
//[3, 4],
//[6, 5, 7],
//[4, 1, 8, 3]
//]
        List<List<Integer>> list = new ArrayList<>();
        List<Integer> subList0 = new ArrayList<>();
        subList0.add(2);
        List<Integer> subList1 = new ArrayList<>();
        subList1.add(3);
        subList1.add(4);
        List<Integer> subList2 = new ArrayList<>();
        subList2.add(6);
        subList2.add(5);
        subList2.add(7);
        List<Integer> subList3 = new ArrayList<>();
        subList3.add(4);
        subList3.add(1);
        subList3.add(8);
        subList3.add(3);

        list.add(subList0);
        list.add(subList1);
        list.add(subList2);
        list.add(subList3);

        System.out.println(new Leetcode_120_Triangle_DP1().minimumTotal(list));
//        System.out.println(new Leetcode_120_Triangle_DP1().minimumTotal2(list));
//        System.out.println(new Leetcode_120_Triangle_DP1().minimumTotal3(list));
    }


    /**
     * DP  使用二維陣列儲存
     *
     * @param triangle
     * @return
     */
    //Runtime: 11 ms, faster than 16.60% of Java online submissions for Triangle.
    public int minimumTotal(List<List<Integer>> triangle) {
        for (int row = triangle.size() - 1; row >= 0; row--) {
            for (int column = triangle.get(row).size() - 1; column >= 1; column--) {
                System.out.println("right:" + triangle.get(row).get(column));
                System.out.println("left:" + triangle.get(row).get(column - 1));
                System.out.println("top:" + triangle.get(row - 1).get(column - 1));
                triangle.get(row - 1).set(column - 1,
                        Math.min(triangle.get(row).get(column) + triangle.get(row - 1).get(column - 1),
                                triangle.get(row).get(column - 1) + triangle.get(row - 1).get(column - 1)));
            }
        }
        return triangle.get(0).get(0);
    }
}

輸出:

right:3
left:8
top:7
right:8
left:1
top:5
right:1
left:4
top:6
right:10
left:6
top:4
right:6
left:7
top:3
right:10
left:9
top:2
11

    /**
     * DP  使用一個一維集合儲存
     *
     * @param triangle
     * @return
     */
    //Runtime: 8 ms, faster than 31.74% of Java online submissions for Triangle.
    public int minimumTotal2(List<List<Integer>> triangle) {
        int row = triangle.size();
        List<Integer> nums = triangle.get(row - 1);
        for (int i = row - 2; i >= 0; i--) {
            for (int j = 0; j <= i; j++) {
                nums.set(j, Math.min(nums.get(j), nums.get(j + 1)) + triangle.get(i).get(j));
            }
        }
        return nums.get(0);
    }

    /**
     * DP  使用一個一維陣列儲存
     *
     * @param triangle
     * @return
     */
    //Runtime: 6 ms, faster than 54.26% of Java online submissions for Triangle.
    //會發現list.get方法會增加時間成本
    public int minimumTotal3(List<List<Integer>> triangle) {
        int row = triangle.size();
        Integer[] nums = new Integer[row];
        for (int i = 0; i < row; i++) {
            nums[i] = triangle.get(row - 1).get(i);
        }

        for (int i = row - 2; i >= 0; i--) {
            for (int j = 0; j <= i; j++) {
                nums[j] = Math.min(nums[j], nums[j + 1]) + triangle.get(i).get(j);
            }
        }
        return nums[0];
    }

當然,用遞迴也行,