auto commit
This commit is contained in:
@ -1,4 +1,44 @@
|
||||
[TOC]
|
||||
<!-- GFM-TOC -->
|
||||
* [斐波那契数列](#斐波那契数列)
|
||||
* [1. 爬楼梯](#1-爬楼梯)
|
||||
* [2. 强盗抢劫](#2-强盗抢劫)
|
||||
* [3. 强盗在环形街区抢劫](#3-强盗在环形街区抢劫)
|
||||
* [4. 信件错排](#4-信件错排)
|
||||
* [5. 母牛生产](#5-母牛生产)
|
||||
* [矩阵路径](#矩阵路径)
|
||||
* [1. 矩阵的最小路径和](#1-矩阵的最小路径和)
|
||||
* [2. 矩阵的总路径数](#2-矩阵的总路径数)
|
||||
* [数组区间](#数组区间)
|
||||
* [1. 数组区间和](#1-数组区间和)
|
||||
* [2. 数组中等差递增子区间的个数](#2-数组中等差递增子区间的个数)
|
||||
* [分割整数](#分割整数)
|
||||
* [1. 分割整数的最大乘积](#1-分割整数的最大乘积)
|
||||
* [2. 按平方数来分割整数](#2-按平方数来分割整数)
|
||||
* [3. 分割整数构成字母字符串](#3-分割整数构成字母字符串)
|
||||
* [最长递增子序列](#最长递增子序列)
|
||||
* [1. 最长递增子序列](#1-最长递增子序列)
|
||||
* [2. 一组整数对能够构成的最长链](#2-一组整数对能够构成的最长链)
|
||||
* [3. 最长摆动子序列](#3-最长摆动子序列)
|
||||
* [最长公共子序列](#最长公共子序列)
|
||||
* [0-1 背包](#0-1-背包)
|
||||
* [1. 划分数组为和相等的两部分](#1-划分数组为和相等的两部分)
|
||||
* [2. 改变一组数的正负号使得它们的和为一给定数](#2-改变一组数的正负号使得它们的和为一给定数)
|
||||
* [3. 01 字符构成最多的字符串](#3-01-字符构成最多的字符串)
|
||||
* [4. 找零钱的最少硬币数](#4-找零钱的最少硬币数)
|
||||
* [5. 找零钱的硬币数组合](#5-找零钱的硬币数组合)
|
||||
* [6. 字符串按单词列表分割](#6-字符串按单词列表分割)
|
||||
* [7. 组合总和](#7-组合总和)
|
||||
* [股票交易](#股票交易)
|
||||
* [1. 需要冷却期的股票交易](#1-需要冷却期的股票交易)
|
||||
* [2. 需要交易费用的股票交易](#2-需要交易费用的股票交易)
|
||||
* [3. 只能进行两次的股票交易](#3-只能进行两次的股票交易)
|
||||
* [4. 只能进行 k 次的股票交易](#4-只能进行-k-次的股票交易)
|
||||
* [字符串编辑](#字符串编辑)
|
||||
* [1. 删除两个字符串的字符使它们相等](#1-删除两个字符串的字符使它们相等)
|
||||
* [2. 编辑距离](#2-编辑距离)
|
||||
* [3. 复制粘贴字符](#3-复制粘贴字符)
|
||||
<!-- GFM-TOC -->
|
||||
|
||||
|
||||
|
||||
|
||||
@ -20,7 +60,7 @@
|
||||
|
||||
<!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[i]=dp[i-1]+dp[i-2]" class="mathjax-pic"/></div> <br>-->
|
||||
|
||||
<img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/14fe1e71-8518-458f-a220-116003061a83.png" width="200px">
|
||||
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/14fe1e71-8518-458f-a220-116003061a83.png" width="200px"> </div><br>
|
||||
|
||||
考虑到 dp[i] 只与 dp[i - 1] 和 dp[i - 2] 有关,因此可以只用两个变量来存储 dp[i - 1] 和 dp[i - 2],使得原来的 O(N) 空间复杂度优化为 O(1) 复杂度。
|
||||
|
||||
@ -53,7 +93,7 @@ public int climbStairs(int n) {
|
||||
|
||||
<!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[i]=max(dp[i-2]+nums[i],dp[i-1])" class="mathjax-pic"/></div> <br>-->
|
||||
|
||||
<img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/2de794ca-aa7b-48f3-a556-a0e2708cb976.jpg" width="350px">
|
||||
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/2de794ca-aa7b-48f3-a556-a0e2708cb976.jpg" width="350px"> </div><br>
|
||||
|
||||
```java
|
||||
public int rob(int[] nums) {
|
||||
@ -109,7 +149,7 @@ private int rob(int[] nums, int first, int last) {
|
||||
|
||||
<!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[i]=(i-1)*dp[i-2]+(i-1)*dp[i-1]" class="mathjax-pic"/></div> <br>-->
|
||||
|
||||
<img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/da1f96b9-fd4d-44ca-8925-fb14c5733388.png" width="350px">
|
||||
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/da1f96b9-fd4d-44ca-8925-fb14c5733388.png" width="350px"> </div><br>
|
||||
|
||||
## 5. 母牛生产
|
||||
|
||||
@ -121,7 +161,7 @@ private int rob(int[] nums, int first, int last) {
|
||||
|
||||
<!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[i]=dp[i-1]+dp[i-3]" class="mathjax-pic"/></div> <br>-->
|
||||
|
||||
<img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/879814ee-48b5-4bcb-86f5-dcc400cb81ad.png" width="250px">
|
||||
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/879814ee-48b5-4bcb-86f5-dcc400cb81ad.png" width="250px"> </div><br>
|
||||
|
||||
# 矩阵路径
|
||||
|
||||
@ -171,7 +211,7 @@ public int minPathSum(int[][] grid) {
|
||||
|
||||
题目描述:统计从矩阵左上角到右下角的路径总数,每次只能向右或者向下移动。
|
||||
|
||||
<img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/dc82f0f3-c1d4-4ac8-90ac-d5b32a9bd75a.jpg" width="">
|
||||
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/dc82f0f3-c1d4-4ac8-90ac-d5b32a9bd75a.jpg" width=""> </div><br>
|
||||
|
||||
```java
|
||||
public int uniquePaths(int m, int n) {
|
||||
@ -392,9 +432,9 @@ public int numDecodings(String s) {
|
||||
|
||||
# 最长递增子序列
|
||||
|
||||
已知一个序列 {S<sub>1</sub>, S<sub>2</sub>,...,S<sub>n</sub>},取出若干数组成新的序列 {S<sub>i1</sub>, S<sub>i2</sub>,..., S<sub>im</sub>},其中 i1、i2 ... im 保持递增,即新序列中各个数仍然保持原数列中的先后顺序,称新序列为原序列的一个 **子序列** 。
|
||||
已知一个序列 {S<sub>1</sub>, S<sub>2</sub>,...,S<sub>n</sub>},取出若干数组成新的序列 {S<sub>i1</sub>, S<sub>i2</sub>,..., S<sub>im</sub>},其中 i1、i2 ... im 保持递增,即新序列中各个数仍然保持原数列中的先后顺序,称新序列为原序列的一个 **子序列** 。
|
||||
|
||||
如果在子序列中,当下标 ix > iy 时,S<sub>ix</sub> > S<sub>iy</sub>,称子序列为原序列的一个 **递增子序列** 。
|
||||
如果在子序列中,当下标 ix > iy 时,S<sub>ix</sub> > S<sub>iy</sub>,称子序列为原序列的一个 **递增子序列** 。
|
||||
|
||||
定义一个数组 dp 存储最长递增子序列的长度,dp[n] 表示以 S<sub>n</sub> 结尾的序列的最长递增子序列长度。对于一个递增子序列 {S<sub>i1</sub>, S<sub>i2</sub>,...,S<sub>im</sub>},如果 im < n 并且 S<sub>im</sub> < S<sub>n</sub>,此时 {S<sub>i1</sub>, S<sub>i2</sub>,..., S<sub>im</sub>, S<sub>n</sub>} 为一个递增子序列,递增子序列的长度增加 1。满足上述条件的递增子序列中,长度最长的那个递增子序列就是要找的,在长度最长的递增子序列上加上 S<sub>n</sub> 就构成了以 S<sub>n</sub> 为结尾的最长递增子序列。因此 dp[n] = max{ dp[i]+1 | S<sub>i</sub> < S<sub>n</sub> && i < n} 。
|
||||
|
||||
@ -402,7 +442,7 @@ public int numDecodings(String s) {
|
||||
|
||||
<!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[n]=max\{1,dp[i]+1|S_i<S_n\&\&i<n\}" class="mathjax-pic"/></div> <br>-->
|
||||
|
||||
<img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/ee994da4-0fc7-443d-ac56-c08caf00a204.jpg" width="350px">
|
||||
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/ee994da4-0fc7-443d-ac56-c08caf00a204.jpg" width="350px"> </div><br>
|
||||
|
||||
对于一个长度为 N 的序列,最长递增子序列并不一定会以 S<sub>N</sub> 为结尾,因此 dp[N] 不是序列的最长递增子序列的长度,需要遍历 dp 数组找出最大值才是所要的结果,max{ dp[i] | 1 <= i <= N} 即为所求。
|
||||
|
||||
@ -575,7 +615,7 @@ public int wiggleMaxLength(int[] nums) {
|
||||
|
||||
<!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[i][j]=\left\{\begin{array}{rcl}dp[i-1][j-1]&&{S1_i==S2_j}\\max(dp[i-1][j],dp[i][j-1])&&{S1_i<>S2_j}\end{array}\right." class="mathjax-pic"/></div> <br>-->
|
||||
|
||||
<img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/ecd89a22-c075-4716-8423-e0ba89230e9a.jpg" width="450px">
|
||||
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/ecd89a22-c075-4716-8423-e0ba89230e9a.jpg" width="450px"> </div><br>
|
||||
|
||||
对于长度为 N 的序列 S<sub>1</sub> 和长度为 M 的序列 S<sub>2</sub>,dp[N][M] 就是序列 S<sub>1</sub> 和序列 S<sub>2</sub> 的最长公共子序列长度。
|
||||
|
||||
@ -615,7 +655,7 @@ public int lengthOfLCS(int[] nums1, int[] nums2) {
|
||||
|
||||
<!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[i][j]=max(dp[i-1][j],dp[i-1][j-w]+v)" class="mathjax-pic"/></div> <br>-->
|
||||
|
||||
<img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/8cb2be66-3d47-41ba-b55b-319fc68940d4.png" width="400px">
|
||||
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/8cb2be66-3d47-41ba-b55b-319fc68940d4.png" width="400px"> </div><br>
|
||||
|
||||
```java
|
||||
// W 为背包总体积
|
||||
@ -638,13 +678,13 @@ public int knapsack(int W, int N, int[] weights, int[] values) {
|
||||
}
|
||||
```
|
||||
|
||||
**空间优化**
|
||||
**空间优化**
|
||||
|
||||
在程序实现时可以对 0-1 背包做优化。观察状态转移方程可以知道,前 i 件物品的状态仅与前 i-1 件物品的状态有关,因此可以将 dp 定义为一维数组,其中 dp[j] 既可以表示 dp[i-1][j] 也可以表示 dp[i][j]。此时,
|
||||
|
||||
<!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[j]=max(dp[j],dp[j-w]+v)" class="mathjax-pic"/></div> <br>-->
|
||||
|
||||
<img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/9ae89f16-7905-4a6f-88a2-874b4cac91f4.jpg" width="300px">
|
||||
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/9ae89f16-7905-4a6f-88a2-874b4cac91f4.jpg" width="300px"> </div><br>
|
||||
|
||||
因为 dp[j-w] 表示 dp[i-1][j-w],因此不能先求 dp[i][j-w],防止将 dp[i-1][j-w] 覆盖。也就是说要先计算 dp[i][j] 再计算 dp[i][j-w],在程序实现时需要按倒序来循环求解。
|
||||
|
||||
@ -663,7 +703,7 @@ public int knapsack(int W, int N, int[] weights, int[] values) {
|
||||
}
|
||||
```
|
||||
|
||||
**无法使用贪心算法的解释**
|
||||
**无法使用贪心算法的解释**
|
||||
|
||||
0-1 背包问题无法使用贪心算法来求解,也就是说不能按照先添加性价比最高的物品来达到最优,这是因为这种方式可能造成背包空间的浪费,从而无法达到最优。考虑下面的物品和一个容量为 5 的背包,如果先添加物品 0 再添加物品 1,那么只能存放的价值为 16,浪费了大小为 2 的空间。最优的方式是存放物品 1 和物品 2,价值为 22.
|
||||
|
||||
@ -673,7 +713,7 @@ public int knapsack(int W, int N, int[] weights, int[] values) {
|
||||
| 1 | 2 | 10 | 5 |
|
||||
| 2 | 3 | 12 | 4 |
|
||||
|
||||
**变种**
|
||||
**变种**
|
||||
|
||||
- 完全背包:物品数量为无限个
|
||||
|
||||
@ -1008,7 +1048,7 @@ public int combinationSum4(int[] nums, int target) {
|
||||
|
||||
题目描述:交易之后需要有一天的冷却时间。
|
||||
|
||||
<img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/ffd96b99-8009-487c-8e98-11c9d44ef14f.png" width="300px">
|
||||
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/ffd96b99-8009-487c-8e98-11c9d44ef14f.png" width="300px"> </div><br>
|
||||
|
||||
```java
|
||||
public int maxProfit(int[] prices) {
|
||||
@ -1051,7 +1091,7 @@ The total profit is ((8 - 1) - 2) + ((9 - 4) - 2) = 8.
|
||||
|
||||
题目描述:每交易一次,都要支付一定的费用。
|
||||
|
||||
<img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/1e2c588c-72b7-445e-aacb-d55dc8a88c29.png" width="300px">
|
||||
<div align="center"> <img src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/1e2c588c-72b7-445e-aacb-d55dc8a88c29.png" width="300px"> </div><br>
|
||||
|
||||
```java
|
||||
public int maxProfit(int[] prices, int fee) {
|
||||
@ -1263,3 +1303,10 @@ public int minSteps(int n) {
|
||||
return dp[n];
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div align="center"><img width="320px" src="https://cs-notes-1256109796.cos.ap-guangzhou.myqcloud.com/githubio/公众号二维码-1.png"></img></div>
|
||||
|
Reference in New Issue
Block a user