前言
最近做了 Leetcode 一些 Dynamic Programming 相关的题目,记录一下思路和解法。
Leetcode 55. Jump Game
题目描述
Given an array of non-negative integers, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Determine if you are able to reach the last index.
Example 1:
Input: [2,3,1,1,4]
Output: true
Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index.
Example 2:
Input: [3,2,1,0,4]
Output: false
Explanation: You will always arrive at index 3 no matter what. Its maximum jump length is 0, which makes it impossible to reach the last index.
解题思路1:暴力递归
遍历每一个元素,每一种跳跃可能,若某一遍历达到随后则返回 True
. 但是该方法问题在于时间效率太低,最坏情况下要遍历每一种可能。会发生Time Exceeding
1 | class Solution: |
解题思路2: DP
遍历过程中保存当前元素下可进行跳跃的最大距离,若最大距离小于等于0而还没有达到数组结尾,返回 False
1 | class Solution: |
解题思路3:另一种途径
从后向前,last
记录在哪个位置可以跳到最后。
1 | class Solution: |
Leetcode 62. Unique Paths
问题描述
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?
Above is a 7 x 3 grid. 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
解题思路 1. 暴力递归法
通过递归遍历每一种可能的走法。但该方法的问题也在于时间复杂度过高,\(O(2^{mn})\)。会导致Time Exceeding
1 | class Solution: |
解题思路2. DP
思路一是通过自上向下递归,试图找到最优解。我们可以换个思路,是否可以从重点出发,计算它邻近的节点达到它的所有可能路径。所以一个点达到终点的可能路径为与他相邻的右方和下方两点可能路径之和。 -- 杨辉三角
1 | class Solution: |
Leetcode 322. Coin Change
题目描述 for 322
You are given coins of different denominations and a total amount of money amount. Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1.
Example 1:
Input: coins = [1, 2, 5], amount = 11
Output: 3
Explanation: 11 = 5 + 5 + 1
Example 2:
Input: coins = [2], amount = 3
Output: -1
Note: You may assume that you have an infinite number of each kind of coin.
解题思路-DP
计算从 0
到 amount
所花费的最少的硬币数。当前 amount
为 n
时,选择 n - c
时的硬币数 + 1
取值最小的。
1 | class Solution { |
进阶思路-递归加减支
基本还是递归的思想,但是增加了减支条件,如果剩下的钱都能被某个最大的 coin
整除,则直接加全部用这个面值硬币的硬币数。
1 | class Solution { |
Leetcode 300. Longest Increasing Subsequence
问题描述
Given an unsorted array of integers, find the length of longest increasing subsequence.
Example:
Input: [10,9,2,5,3,7,101,18]
Output: 4
Explanation: The longest increasing subsequence is [2,3,7,101], therefore the length is 4.
Note:
- There may be more than one LIS combination, it is only necessary for you to return the length.
- Your algorithm should run in O(n2) complexity.
Follow up: Could you improve it to O(n log n) time complexity?
解题思路1-DP
状态设计: dp[i]
代表以 nums[i]
结尾的 LIS 长度。
状态转移: dp[i] = max(dp[i], dp[j]+1) (0<=j<i, a[j]<a[i])
边界处理: dp[i] = 1 (0<=j<n)
时间复杂度: O(N^2)
1 | class Solution { |
进阶思路 贪心+二分查找
第一步中在第二个循环查找插入的子序列时可以优化为二分查找,时间复杂度变为 O(nlogn)
1 | class Solution { |
进阶写法 lower_bound
1 | class Solution { |