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.

Example

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).

Note

Bonus point if you are able to do this using only O(n) extra space, where n is the total number of rows in the triangle.

Version 1. Up-Bottom

想法直白 但是做起来麻烦 要考虑很多边界条件 不推荐

//f[i][j] = Math.min(f[i-1][j-1], f[i-1][j])+grid[i][j]
public int minimumTotal(ArrayList<ArrayList<Integer>> triangle) {
    //O(n^2) space
    //f[i][j] = Math.min(f[i-1][j-1], f[i-1][j])+grid[i][j]
    if (triangle == null || triangle.size() == 0) {
        return 0;
    }
    int size = triangle.size();
    int[][] resultMap = new int[size][size];
    resultMap[0][0] = triangle.get(0).get(0);
    for (int i = 1; i < size; i++) {
        ArrayList<Integer> curr = triangle.get(i);
        for (int j = 0; j < curr.size(); j++) {
            if (j == 0) {
                resultMap[i][j] = resultMap[i - 1][j] + curr.get(j);
            } else {
                if (j < triangle.get(i - 1).size()) {
                    resultMap[i][j] = Math.min(resultMap[i - 1][j - 1], resultMap[i - 1][j]) + curr.get(j);
                } else {
                    resultMap[i][j] = resultMap[i - 1][j - 1] + curr.get(j);
                }
            }
        }
    }
    int min = Integer.MAX_VALUE;
    for (int i = 0; i < size; i++) {
        if (resultMap[size - 1][i] < min) {
            min = resultMap[size - 1][i];
        }
    }
    return min;
}

Version 2. Bottom-Up O(n^2) space

可以想成求从底部任一点出发到左上角的最小路径和 代码简洁 不会outOfBound

    public int minimumTotal(ArrayList < ArrayList < Integer >> triangle) {
    	if (triangle == null || triangle.size() == 0) {
    		return 0;
    	}
    	int size = triangle.size();
    	int[][] resultMap = new int[size][size];
    	//init the last row
    	ArrayList < Integer > lastRow = triangle.get(size - 1);
    	for (int i = 0; i < size; i++) {
    		resultMap[size - 1][i] = lastRow.get(i);
    	}
    	//from bottom to top
    	for (int i = size - 2; i >= 0; i--) {
    		ArrayList < Integer > curr = triangle.get(i);
    		for (int j = 0; j < curr.size(); j++) {
    			resultMap[i][j] = Math.min(resultMap[i + 1][j], resultMap[i + 1][j + 1]) + curr.get(j);
    		}
    	}
    	return resultMap[0][0];
    }

Version 3. Bottom-Up O(n) space

在Version 2的基础上 只用2*n的数组记录数据

代码不变 只需要行数mod 2 (modulus %) 就行了

    public int minimumTotal(ArrayList < ArrayList < Integer >> triangle) {
    	if (triangle == null || triangle.size() == 0) {
    		return 0;
    	}
    	int size = triangle.size();
    	int[][] resultMap = new int[2][size];
    	//init the last row
    	ArrayList < Integer > lastRow = triangle.get(size - 1);
    	for (int i = 0; i < size; i++) {
    		resultMap[(size - 1) % 2][i] = lastRow.get(i);
    	}
    	//from bottom to top
    	for (int i = size - 2; i >= 0; i--) {
    		ArrayList < Integer > curr = triangle.get(i);
    		for (int j = 0; j < curr.size(); j++) {
    			resultMap[i % 2][j] = Math.min(resultMap[(i + 1) % 2][j], resultMap[(i + 1) % 2][j + 1]) + curr.get(j);
    		}
    	}
    	return resultMap[0][0];
    }
FacebookTwitterGoogle+Share

Unique Path II

Follow up for “Unique Paths”:

Now consider if some obstacles are added to the grids. How many unique paths would there be?

An obstacle and empty space is marked as 1 and 0 respectively in the grid.

Example

For example,

There is one obstacle in the middle of a 3×3 grid as illustrated below.

[
  [0,0,0],
  [0,1,0],
  [0,0,0]
]

The total number of unique paths is 2.

Note

m and n will be at most 100.

    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
    	// write your code here
    	if (obstacleGrid == null || obstacleGrid.length == 0 || obstacleGrid[0].length == 0 || obstacleGrid[0][0] == 1) {
    		return 0;
    	}
    	int row = obstacleGrid.length;
    	int col = obstacleGrid[0].length;
    	int[][] path = new int[row][col];
    	path[0][0] = 1;
    	//init first col
    	for (int i = 1; i < row; i++) {
    		path[i][0] = obstacleGrid[i][0] == 1 ? 0 : path[i - 1][0];
    	}
    	//init first row
    	for (int j = 1; j < col; j++) {
    		path[0][j] = obstacleGrid[0][j] == 1 ? 0 : path[0][j - 1];
    	}
    	for (int i = 1; i < row; i++) {
    		for (int j = 1; j < col; j++) {
    			path[i][j] = obstacleGrid[i][j] == 1 ? 0 : path[i - 1][j] + path[i][j - 1];
    		}
    	}
    	return path[row - 1][col - 1];
    }