|
4 | 4 |
|
5 | 5 | 记忆化搜索是动态规划的一种实现方式。在记忆化搜索中,当算法需要计算某个子问题的结果时,它首先检查是否已经计算过该问题。如果已经计算过,则直接返回已经存储的结果;否则,计算该问题,并将结果存储下来以备将来使用。
|
6 | 6 |
|
7 | | -举个例子,比如「斐波那契数列」的定义是:`f(1) = 1, f(2) = 2, f(n) = f(n - 1) + f(n - 2)`。如果我们使用递归算法求解第 $n$ 个斐波那契数,则对应的递推过程如下: |
| 7 | +举个例子,比如「斐波那契数列」的定义是:$f(0) = 0, f(1) = 1, f(n) = f(n - 1) + f(n - 2)$。如果我们使用递归算法求解第 $n$ 个斐波那契数,则对应的递推过程如下: |
8 | 8 |
|
9 | | - |
| 9 | + |
10 | 10 |
|
11 | | -从图中可以看出:如果使用普通递归算法,想要计算 `f(5)`,需要先计算 `f(4)` 和 `f(3)`,而在计算 `f(4)` 时还需要计算 `f(3)`。这样 `f(3)` 就进行了多次计算。 |
| 11 | +从图中可以看出:如果使用普通递归算法,想要计算 $f(5)$,需要先计算 $f(3)$ 和 $f(4)$,而在计算 $f(4)$ 时还需要计算 $f(3)$。这样 $f(3)$ 就进行了多次计算,同理 $f(0)$、$f(1)$、$f(2)$ 都进行了多次计算,从而导致了重复计算问题。 |
12 | 12 |
|
13 | | -为了避免重复计算,我们可以使用一个缓存(数组或哈希表)来保存已经求解过的 `f(k)` 的结果。如上图所示,当递归调用用到 `f(k)` 时,先查看一下之前是否已经计算过结果,如果已经计算过,则直接从缓存中取值返回,而不用再递推下去,这样就避免了重复计算问题。 |
| 13 | +为了避免重复计算,在递归的同时,我们可以使用一个缓存(数组或哈希表)来保存已经求解过的 $f(k)$ 的结果。如上图所示,当递归调用用到 $f(k)$ 时,先查看一下之前是否已经计算过结果,如果已经计算过,则直接从缓存中取值返回,而不用再递推下去,这样就避免了重复计算问题。 |
14 | 14 |
|
15 | 15 | 使用「记忆化搜索」方法解决斐波那契数列的代码如下:
|
16 | 16 |
|
@@ -81,9 +81,9 @@ class Solution:
|
81 | 81 |
|
82 | 82 | #### 4.1.2 题目大意
|
83 | 83 |
|
84 | | -**描述**:给定一个整数数组 `nums` 和一个整数 `target`。数组长度不超过 `20`。向数组中每个整数前加 `+` 或 `-`。然后串联起来构造成一个表达式。 |
| 84 | +**描述**:给定一个整数数组 $nums$ 和一个整数 $target$。数组长度不超过 20ドル$。向数组中每个整数前加 `+` 或 `-`。然后串联起来构造成一个表达式。 |
85 | 85 |
|
86 | | -**要求**:返回通过上述方法构造的、运算结果等于 `target` 的不同表达式数目。 |
| 86 | +**要求**:返回通过上述方法构造的、运算结果等于 $target$ 的不同表达式数目。 |
87 | 87 |
|
88 | 88 | **说明**:
|
89 | 89 |
|
@@ -120,14 +120,14 @@ class Solution:
|
120 | 120 |
|
121 | 121 | 使用深度优先搜索对每位数字进行 `+` 或者 `-`,具体步骤如下:
|
122 | 122 |
|
123 | | -1. 定义从位置 `0`、和为 `0` 开始,到达数组尾部位置为止,和为 `target` 的方案数为 `dfs(0, 0)`,`size`。 |
124 | | -2. 下面从位置 `0`、和为 `0` 开始,以深度优先搜索遍历每个位置。 |
125 | | -3. 如果当前位置 `i` 到达最后一个位置 `size`: |
126 | | - 1. 如果和 `cur_sum` 等于目标和 `target`,则返回方案数 `1`。 |
127 | | - 2. 如果和 `cur_sum` 不等于目标和 `target`,则返回方案数 `0`。 |
128 | | -4. 递归搜索 `i + 1` 位置,和为 `cur_sum - nums[i]` 的方案数。 |
129 | | -5. 递归搜索 `i + 1` 位置,和为 `cur_sum + nums[i]` 的方案数。 |
130 | | -6. 将 4 ~ 5 两个方案数加起来就是当前位置 `i`、和为 `cur_sum` 的方案数,返回该方案数。 |
| 123 | +1. 定义从位置 0ドル$、和为 0ドル$ 开始,到达数组尾部位置为止,和为 $target$ 的方案数为 `dfs(0, 0)`。 |
| 124 | +2. 下面从位置 0ドル$、和为 0ドル$ 开始,以深度优先搜索遍历每个位置。 |
| 125 | +3. 如果当前位置 $i$ 到达最后一个位置 $size$: |
| 126 | + 1. 如果和 `cur_sum` 等于目标和 $target$,则返回方案数 1ドル$。 |
| 127 | + 2. 如果和 `cur_sum` 不等于目标和 $target$,则返回方案数 0ドル$。 |
| 128 | +4. 递归搜索 $i + 1$ 位置,和为 `cur_sum - nums[i]` 的方案数。 |
| 129 | +5. 递归搜索 $i + 1$ 位置,和为 `cur_sum + nums[i]` 的方案数。 |
| 130 | +6. 将 4 ~ 5 两个方案数加起来就是当前位置 $i$、和为 `cur_sum` 的方案数,返回该方案数。 |
131 | 131 | 7. 最终方案数为 `dfs(0, 0)`,将其作为答案返回即可。
|
132 | 132 |
|
133 | 133 | ##### 思路 1:代码
|
@@ -158,18 +158,18 @@ class Solution:
|
158 | 158 |
|
159 | 159 | 在思路 1 中我们单独使用深度优先搜索对每位数字进行 `+` 或者 `-` 的方法超时了。所以我们考虑使用记忆化搜索的方式,避免进行重复搜索。
|
160 | 160 |
|
161 | | -这里我们使用哈希表 `table` 记录遍历过的位置 `i` 及所得到的的当前和`cur_sum` 下的方案数,来避免重复搜索。具体步骤如下: |
162 | | - |
163 | | -1. 定义从位置 `0`、和为 `0` 开始,到达数组尾部位置为止,和为 `target` 的方案数为 `dfs(0, 0)`。 |
164 | | -2. 下面从位置 `0`、和为 `0` 开始,以深度优先搜索遍历每个位置。 |
165 | | -3. 如果当前位置 `i` 遍历完所有位置: |
166 | | - 1. 如果和 `cur_sum` 等于目标和 `target`,则返回方案数 `1`。 |
167 | | - 2. 如果和 `cur_sum` 不等于目标和 `target`,则返回方案数 `0`。 |
168 | | -4. 如果当前位置 `i`、和为 `cur_sum` 之前记录过(即使用 `table` 记录过对应方案数),则返回该方案数。 |
169 | | -5. 如果当前位置 `i`、和为 `cur_sum` 之前没有记录过,则: |
170 | | - 1. 递归搜索 `i + 1` 位置,和为 `cur_sum - nums[i]` 的方案数。 |
171 | | - 2. 递归搜索 `i + 1` 位置,和为 `cur_sum + nums[i]` 的方案数。 |
172 | | - 3. 将上述两个方案数加起来就是当前位置 `i`、和为 `cur_sum` 的方案数,将其记录到哈希表 `table` 中,并返回该方案数。 |
| 161 | +这里我们使用哈希表 $table$ 记录遍历过的位置 $i$ 及所得到的的当前和`cur_sum` 下的方案数,来避免重复搜索。具体步骤如下: |
| 162 | + |
| 163 | +1. 定义从位置 0ドル$、和为 0ドル$ 开始,到达数组尾部位置为止,和为 $target$ 的方案数为 `dfs(0, 0)`。 |
| 164 | +2. 下面从位置 0ドル$、和为 0ドル$ 开始,以深度优先搜索遍历每个位置。 |
| 165 | +3. 如果当前位置 $i$ 遍历完所有位置: |
| 166 | + 1. 如果和 `cur_sum` 等于目标和 $target$,则返回方案数 1ドル$。 |
| 167 | + 2. 如果和 `cur_sum` 不等于目标和 $target$,则返回方案数 0ドル$。 |
| 168 | +4. 如果当前位置 $i$、和为 `cur_sum` 之前记录过(即使用 $table$ 记录过对应方案数),则返回该方案数。 |
| 169 | +5. 如果当前位置 $i$、和为 `cur_sum` 之前没有记录过,则: |
| 170 | + 1. 递归搜索 $i + 1$ 位置,和为 `cur_sum - nums[i]` 的方案数。 |
| 171 | + 2. 递归搜索 $i + 1$ 位置,和为 `cur_sum + nums[i]` 的方案数。 |
| 172 | + 3. 将上述两个方案数加起来就是当前位置 $i$、和为 `cur_sum` 的方案数,将其记录到哈希表 $table$ 中,并返回该方案数。 |
173 | 173 | 6. 最终方案数为 `dfs(0, 0)`,将其作为答案返回即可。
|
174 | 174 |
|
175 | 175 | ##### 思路 2:代码
|
@@ -244,7 +244,7 @@ T_4 =わ 1 +たす 1 +たす 2 =わ 4
|
244 | 244 | ##### 思路 1:记忆化搜索
|
245 | 245 |
|
246 | 246 | 1. 问题的状态定义为:第 $n$ 个泰波那契数。其状态转移方程为:$T_0 = 0, T_1 = 1, T_2 = 1,ドル且在 $n >= 0$ 的条件下,$T_{n + 3} = T_{n} + T_{n+1} + T_{n+2}$。
|
247 | | -2. 定义一个长度为 $n + 1$ 数组 `memo` 用于保存一斤个计算过的泰波那契数。 |
| 247 | +2. 定义一个长度为 $n + 1$ 数组 $memo$ 用于保存一斤个计算过的泰波那契数。 |
248 | 248 | 3. 定义递归函数 `my_tribonacci(n, memo)`。
|
249 | 249 | 1. 当 $n = 0$ 或者 $n = 1,ドル或者 $n = 2$ 时直接返回结果。
|
250 | 250 | 2. 当 $n > 2$ 时,首先检查是否计算过 $T(n),ドル即判断 $memo[n]$ 是否等于 0ドル$。
|
|
0 commit comments