LeetCode刷题笔记-动态规划

119 阅读3分钟

120 Triangle Medium

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

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.

我的方法:

从第二行开始计算,每一行下标loc的数 = 自身 + min(上一行下标loc-1的数,上一行下标loc的数),loc-1与loc需要判断在上一行是否越界。

最后一行的最小值就是结果。

class Solution {
    public int minimumTotal(List<List<Integer>> triangle) {
        if(triangle == null || triangle.size() == 0 || triangle.get(0).size() == 0) {
            return 0;
        }
        List<List<Integer>> status = new ArrayList<>();
        List<Integer> first = new ArrayList<>();
        first.add(triangle.get(0).get(0));
        status.add(first);
        for(int i=1; i<triangle.size(); i++) {
            List<Integer> line = new ArrayList<>();
            int j=0;
            while(j<i+1) {
                int left = Integer.MAX_VALUE;
                int right = Integer.MAX_VALUE;
                if(j-1>=0) {
                    left = status.get(i-1).get(j-1);
                }
                if(j<status.get(i-1).size()) {
                    right = status.get(i-1).get(j);
                }
                line.add(triangle.get(i).get(j) + Math.min(left, right));
                j++;
            }
            status.add(line);
        }
        Object[] lastLine = status.get(triangle.size()-1).toArray();
        Arrays.sort(lastLine);
        return (int)lastLine[0];
    }
}

更好的方法:

反过来,从倒数第二行开始计算。

f(i,j) 为从位置 (i,j) 出发,路径的最小和,则 f(i,j) = min{f(i+1,j),f(i+1,j+1)} + (i,j)

最后求到f(0,0)就是结果。

class Solution {
    public int minimumTotal(List<List<Integer>> triangle) {
        if(triangle == null || triangle.size() == 0 || triangle.get(0).size() == 0) {
            return 0;
        }               

        for(int i= triangle.size()-2; i>=0; i--) {
            for(int j=0; j<i+1; j++) {
                int cur = triangle.get(i).get(j);
                triangle.get(i).set(j, cur + Math.min(triangle.get(i+1).get(j), triangle.get(i+1).get(j+1)));
            }
        }
        return triangle.get(0).get(0);
    }
}

53 Maximum Subarray Easy

Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.

Example:

Input: [-2,1,-3,4,-1,2,1,-5,4],

Output: 6

Explanation: [4,-1,2,1] has the largest sum = 6.

Follow up:

If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.

经典题:最大连续子序列和

从头到尾依次遍历数组元素,对每一个元素,有两种选择:加入之前的SubArray,自己另起一个SubArray。

设状态为f[j],表示以S[j]结尾的最大连续子序列和,则状态转移方程:

f[j] = max{f[j-1]+S[j], S[j]}, i≤j≤n

target = max{f[j]}, i≤j≤n

class Solution {
    public int maxSubArray(int[] nums) {
        if(nums == null || nums.length == 0) {
            return 0;
        }
        int result = Integer.MIN_VALUE;
        int preSum = 0;
        for(int i=0; i<nums.length; i++) {
            preSum = Math.max(preSum + nums[i], nums[i]);
            result = Math.max(preSum, result);
        }
        return result;
    }
}

375 Guess Number Higher or Lower II Medium

We are playing the Guess Game. The game is as follows: I pick a number from 1 to n. You have to guess which number I picked. Every time you guess wrong, I'll tell you whether the number I picked is higher or lower. However, when you guess a particular number x, and you guess wrong, you pay x dollars. You win the game when you guess the number I picked. Example: n = 10, I pick 8. First round: You guess 5, I tell you that it's higher. You pay 5 dollars. Second round: You guess 7, I tell you that it's higher. You pay 7 dollars. Third round: You guess 9, I tell you that it's lower. You pay 9 dollars. Game over. 8 is the number I picked. You end up paying 5 + 7 + 9 = 21. Given a particular n ≥ 1, find out how much money you need to have to guarantee a win.

参考:www.hrwhisper.me/leetcode-gu…

62 Unique Paths Medium

A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below).

The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below).

How many possible unique paths are there?

Note: m and n will be at most 100.

Example 1:

Input: m = 3, n = 2

Output: 3

Explanation:

From the top-left corner, there are a total of 3 ways to reach the bottom-right corner:

  1. Right -> Right -> Down
  2. Right -> Down -> Right
  3. Down -> Right -> Right

Example 2:

Input: m = 7, n = 3

Output: 28

image.png

f(i,j)表示从起点(i,j)到达(i,j)的路线数

状态转移方程:f(i,j) = f(i-1,j)+f(i,j-1)

class Solution {
    public int uniquePaths(int m, int n) {
        int[][] dp = new int[m + 1][n + 1];
        for (int i = 1; i < m + 1; i++) {
            for (int j = 1; j < n + 1; j++) {
                if (i == 1 && j == 1) {
                    dp[i][j] = 1;
                    continue;
                }
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
            }
        }
        return dp[m][n];
    }
}