Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 10196df

Browse files
committed
更新题解列表
1 parent 75f2511 commit 10196df

File tree

2 files changed

+74
-20
lines changed

2 files changed

+74
-20
lines changed

‎Solutions/0516. 最长回文子序列.md‎

Lines changed: 57 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,70 @@
55

66
## 题目大意
77

8-
给定一个字符串 `s`,找出其中最长的回文子序列,并返回该序列的长度。
8+
**描述**:给定一个字符串 $s$。
9+
10+
**要求**:找出其中最长的回文子序列,并返回该序列的长度。
11+
12+
**说明**:
13+
14+
- **子序列**:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。
15+
- 1ドル \le s.length \le 1000$。
16+
- $s$ 仅由小写英文字母组成。
17+
18+
**示例**:
19+
20+
- 示例 1:
21+
22+
```Python
23+
输入:s = "bbbab"
24+
输出:4
25+
解释:一个可能的最长回文子序列为 "bbbb"
26+
```
27+
28+
- 示例 2:
29+
30+
```Python
31+
输入:s = "cbbd"
32+
输出:2
33+
解释:一个可能的最长回文子序列为 "bb"
34+
```
935

1036
## 解题思路
1137

12-
动态规划求解。
38+
### 思路 1:动态规划
39+
40+
###### 1. 划分阶段
41+
42+
按照区间长度进行阶段划分。
43+
44+
###### 2. 定义状态
1345

14-
定义状态 `dp[i][j]` 表示为:字符串 `s``[i, j]` 范围内的最长回文子序列长度。
46+
定义状态 $dp[i][j]$ 表示为:字符串 $s$ 在区间 $[i, j]$ 范围内的最长回文子序列长度。
1547

16-
则状态转移公式为:
48+
###### 3. 状态转移方程
1749

18-
- 如果 `s[i] == s[j]`,则 `dp[i][j]``[i + 1, j - 1]` 范围内最长回文子序列长度 + 2,即 `dp[i][j] = dp[i + 1][j - 1] + 2`
50+
我们对区间 $[i, j]$ 边界位置上的字符 $s[i]$ 与 $s[j]$ 进行分类讨论:
1951

20-
- 如果 `s[i] != s[j]`,则 `dp[i][j]` 取决于以下两种情况,取其最大的一种:
52+
1. 如果 $s[i] = s[j],ドル则 $dp[i][j]$ 为区间 $[i + 1, j - 1]$ 范围内最长回文子序列长度 + 2ドル,ドル即 $dp[i][j] = dp[i + 1][j - 1] + 2$。
53+
2. 如果 $s[i] \ne s[j],ドル则 $dp[i][j]$ 取决于以下两种情况,取其最大的一种:
54+
1. 加入 $s[i]$ 所能组成的最长回文子序列长度,即:$dp[i][j] = dp[i][j - 1]$。
55+
2. 加入 $s[j]$ 所能组成的最长回文子序列长度,即:$dp[i][j] = dp[i - 1][j]$。
2156

22-
- 加入 `s[i]` 所能组成的最长回文子序列长度,即:`dp[i][j] = dp[i][j - 1]`
23-
- 加入 `s[j]` 所能组成的最长回文子序列长度,即:`dp[i][j] = dp[i - 1][j]`
57+
则状态转移方程为:
2458

25-
下一步确定遍历方向。
59+
$dp[i][j] = \begin{cases} max \lbrace dp[i + 1][j - 1] + 2 \rbrace & s[i] = s[j] \cr max \lbrace dp[i][j - 1], dp[i - 1][j] \rbrace & s[i] \ne s[j] \end{cases}$
2660

27-
由于 `dp[i][j]` 依赖于 `dp[i + 1][j - 1]``dp[i + 1][j]``dp[i][j - 1]`,所以我们应该按照从下到上、从左到右的顺序进行遍历。
61+
###### 4. 初始条件
2862

29-
最后输出 `[0, size - 1]` 范围内最长回文子序列长度,即 `dp[0][size - 1]` 为最终答案
63+
- 单个字符的最长回文序列是 1ドル$,即 $dp[i][i] = 1$
3064

31-
## 代码
65+
###### 5. 最终结果
66+
67+
由于 $dp[i][j]$ 依赖于 $dp[i + 1][j - 1]$、$dp[i + 1][j]$、$dp[i][j - 1],ドル所以我们应该按照从下到上、从左到右的顺序进行遍历。
68+
69+
根据我们之前定义的状态,$dp[i][j]$ 表示为:字符串 $s$ 在区间 $[i, j]$ 范围内的最长回文子序列长度。所以最终结果为 $dp[0][size - 1]$。
70+
71+
### 思路 1:代码
3272

3373
```Python
3474
class Solution:
@@ -48,3 +88,8 @@ class Solution:
4888
return dp[0][size - 1]
4989
```
5090

91+
### 思路 1:复杂度分析
92+
93+
- **时间复杂度**:$O(n^2),ドル其中 $n$ 为字符串 $s$ 的长度。
94+
- **空间复杂度**:$O(n^2)$。
95+

‎Solutions/1547. 切棍子的最小成本.md‎

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,32 +44,39 @@
4444
```Python
4545
输入:n = 9, cuts = [5,6,1,4,2]
4646
输出:22
47-
解释:如果按给定的顺序切割,则总成本为 25。总成本 <= 25 的切割顺序很多,例如,[4, 6, 5, 2, 1] 的总成本 = 22,是所有可能方案中成本最小的。
47+
解释:如果按给定的顺序切割,则总成本为 25。总成本 <= 25 的切割顺序很多,例如,[4, 6, 5, 2, 1] 的总成本 = 22,是所有可能方案中成本最小的。
4848
```
4949

5050
## 解题思路
5151

5252
### 思路 1:动态规划
5353

54+
我们可以预先在数组 $cuts$ 种添加位置 0ドル$ 和位置 $n,ドル然后对数组 $cuts$ 进行排序。这样待切割的木棍就对应了数组中连续元素构成的「区间」。
55+
5456
###### 1. 划分阶段
5557

56-
按照 进行阶段划分
58+
按照区间长度进行阶段划分
5759

5860
###### 2. 定义状态
5961

60-
定义状态 $dp[i]$ 表示为:。
62+
定义状态 $dp[i][j]$ 表示为:切割区间为 $[i, j]$ 上的小木棍的最小成本
6163

6264
###### 3. 状态转移方程
6365

66+
假设位置 $i$ 与位置 $j$ 之间最后一个切割的位置为 $k,ドル则 $dp[i][j]$ 取决与由 $k$ 作为切割点分割出的两个区间 $[i, k]$ 与 $[k, j]$ 上的最小成本 + 切割位置 $k$ 所带来的成本。
6467

68+
而切割位置 $k$ 所带来的成本是这段区间所代表的小木棍的长度,即 $cuts[j] - cuts[i]$。
6569

66-
###### 4. 初始条件
70+
则状态转移方程为:$dp[i][j] = min \lbrace dp[i][k] + dp[k][j] + cuts[j] - cuts[i] \rbrace, \quad i < k < j$
6771

72+
###### 4. 初始条件
6873

74+
- 相邻位置之间没有切割点,不需要切割,最小成本为 0ドル,ドル即 $dp[i - 1][i] = 0$。
75+
- 其余位置默认为最小成本为一个极大值,即 $dp[i][j] = \infty, \quad i + 1 \ne j$。
6976

7077
###### 5. 最终结果
7178

72-
根据我们之前定义的状态,$dp[i]$ 表示为:。 所以最终结果为 $dp[size]$。
79+
根据我们之前定义的状态,$dp[i][j]$ 表示为:切割区间为 $[i, j]$ 上的小木棍的最小成本。 所以最终结果为 $dp[0][size - 1]$。
7380

7481
### 思路 1:代码
7582

@@ -81,7 +88,9 @@ class Solution:
8188
cuts.sort()
8289

8390
size = len(cuts)
84-
dp = [[0 for _ in range(size)] for _ in range(size)]
91+
dp = [[float('inf') for _ in range(size)] for _ in range(size)]
92+
for i in range(1, size):
93+
dp[i - 1][i] = 0
8594

8695
for l in range(3, size + 1): # 枚举区间长度
8796
for i in range(size): # 枚举区间起点
@@ -97,5 +106,5 @@ class Solution:
97106

98107
### 思路 1:复杂度分析
99108

100-
- **时间复杂度**:$O()$
101-
- **空间复杂度**:
109+
- **时间复杂度**:$O(m^3),ドル其中 $m$ 为数组 $cuts$ 的元素个数。
110+
- **空间复杂度**:$O(m^2)$。

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /