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 5d344fc

Browse files
Merge pull request youngyangyang04#2133 from jianghongcheng/master
merge
2 parents 84ebe52 + 0a742d8 commit 5d344fc

5 files changed

+199
-36
lines changed

‎problems/0300.最长上升子序列.md‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ class Solution {
148148
```
149149

150150
Python:
151+
152+
DP
151153
```python
152154
class Solution:
153155
def lengthOfLIS(self, nums: List[int]) -> int:
@@ -162,7 +164,31 @@ class Solution:
162164
result = max(result, dp[i]) #取长的子序列
163165
return result
164166
```
167+
贪心
168+
```python
169+
class Solution:
170+
def lengthOfLIS(self, nums: List[int]) -> int:
171+
if len(nums) <= 1:
172+
return len(nums)
173+
174+
tails = [nums[0]] # 存储递增子序列的尾部元素
175+
for num in nums[1:]:
176+
if num > tails[-1]:
177+
tails.append(num) # 如果当前元素大于递增子序列的最后一个元素,直接加入到子序列末尾
178+
else:
179+
# 使用二分查找找到当前元素在递增子序列中的位置,并替换对应位置的元素
180+
left, right = 0, len(tails) - 1
181+
while left < right:
182+
mid = (left + right) // 2
183+
if tails[mid] < num:
184+
left = mid + 1
185+
else:
186+
right = mid
187+
tails[left] = num
188+
189+
return len(tails) # 返回递增子序列的长度
165190

191+
```
166192
Go:
167193
```go
168194
// 动态规划求解

‎problems/0309.最佳买卖股票时机含冷冻期.md‎

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -248,23 +248,51 @@ class Solution {
248248
```
249249

250250
Python:
251-
251+
版本一
252252
```python
253+
from typing import List
254+
253255
class Solution:
254256
def maxProfit(self, prices: List[int]) -> int:
255257
n = len(prices)
256258
if n == 0:
257259
return 0
258-
dp = [[0] * 4 for _ in range(n)]
259-
dp[0][0] = -prices[0] #持股票
260+
dp = [[0] * 4 for _ in range(n)]# 创建动态规划数组,4个状态分别表示持有股票、不持有股票且处于冷冻期、不持有股票且不处于冷冻期、不持有股票且当天卖出后处于冷冻期
261+
dp[0][0] = -prices[0] # 初始状态:第一天持有股票的最大利润为买入股票的价格
260262
for i in range(1, n):
261-
dp[i][0] = max(dp[i-1][0], max(dp[i-1][3], dp[i-1][1]) - prices[i])
262-
dp[i][1] = max(dp[i-1][1], dp[i-1][3])
263-
dp[i][2] = dp[i-1][0] + prices[i]
264-
dp[i][3] = dp[i-1][2]
265-
return max(dp[n-1][3], dp[n-1][1], dp[n-1][2])
263+
dp[i][0] = max(dp[i-1][0], max(dp[i-1][3], dp[i-1][1]) - prices[i]) # 当前持有股票的最大利润等于前一天持有股票的最大利润或者前一天不持有股票且不处于冷冻期的最大利润减去当前股票的价格
264+
dp[i][1] = max(dp[i-1][1], dp[i-1][3]) # 当前不持有股票且处于冷冻期的最大利润等于前一天持有股票的最大利润加上当前股票的价格
265+
dp[i][2] = dp[i-1][0] + prices[i] # 当前不持有股票且不处于冷冻期的最大利润等于前一天不持有股票的最大利润或者前一天处于冷冻期的最大利润
266+
dp[i][3] = dp[i-1][2] # 当前不持有股票且当天卖出后处于冷冻期的最大利润等于前一天不持有股票且不处于冷冻期的最大利润
267+
return max(dp[n-1][3], dp[n-1][1], dp[n-1][2]) # 返回最后一天不持有股票的最大利润
268+
266269
```
270+
版本二
271+
```python
272+
class Solution:
273+
def maxProfit(self, prices: List[int]) -> int:
274+
n = len(prices)
275+
if n < 2:
276+
return 0
277+
278+
# 定义三种状态的动态规划数组
279+
dp = [[0] * 3 for _ in range(n)]
280+
dp[0][0] = -prices[0] # 持有股票的最大利润
281+
dp[0][1] = 0 # 不持有股票,且处于冷冻期的最大利润
282+
dp[0][2] = 0 # 不持有股票,不处于冷冻期的最大利润
283+
284+
for i in range(1, n):
285+
# 当前持有股票的最大利润等于前一天持有股票的最大利润或者前一天不持有股票且不处于冷冻期的最大利润减去当前股票的价格
286+
dp[i][0] = max(dp[i-1][0], dp[i-1][2] - prices[i])
287+
# 当前不持有股票且处于冷冻期的最大利润等于前一天持有股票的最大利润加上当前股票的价格
288+
dp[i][1] = dp[i-1][0] + prices[i]
289+
# 当前不持有股票且不处于冷冻期的最大利润等于前一天不持有股票的最大利润或者前一天处于冷冻期的最大利润
290+
dp[i][2] = max(dp[i-1][2], dp[i-1][1])
291+
292+
# 返回最后一天不持有股票的最大利润
293+
return max(dp[-1][1], dp[-1][2])
267294

295+
```
268296
Go:
269297
```go
270298
// 最佳买卖股票时机含冷冻期 动态规划

‎problems/0674.最长连续递增序列.md‎

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ public static int findLengthOfLCIS(int[] nums) {
208208

209209
Python:
210210

211-
> 动态规划:
211+
DP
212212
```python
213213
class Solution:
214214
def findLengthOfLCIS(self, nums: List[int]) -> int:
@@ -223,8 +223,27 @@ class Solution:
223223
return result
224224
```
225225

226+
DP(优化版)
227+
```python
228+
class Solution:
229+
def findLengthOfLCIS(self, nums: List[int]) -> int:
230+
if not nums:
231+
return 0
232+
233+
max_length = 1
234+
current_length = 1
226235

227-
> 贪心法:
236+
for i in range(1, len(nums)):
237+
if nums[i] > nums[i - 1]:
238+
current_length += 1
239+
max_length = max(max_length, current_length)
240+
else:
241+
current_length = 1
242+
243+
return max_length
244+
245+
```
246+
贪心
228247
```python
229248
class Solution:
230249
def findLengthOfLCIS(self, nums: List[int]) -> int:

‎problems/0718.最长重复子数组.md‎

Lines changed: 79 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -302,37 +302,99 @@ class Solution {
302302

303303
Python:
304304

305-
> 动态规划:
305+
2维DP
306306
```python
307307
class Solution:
308-
def findLength(self, A: List[int], B: List[int]) -> int:
309-
dp = [[0] * (len(B)+1) for _ in range(len(A)+1)]
308+
def findLength(self, nums1: List[int], nums2: List[int]) -> int:
309+
# 创建一个二维数组 dp,用于存储最长公共子数组的长度
310+
dp = [[0] * (len(nums2) + 1) for _ in range(len(nums1) + 1)]
311+
# 记录最长公共子数组的长度
310312
result = 0
311-
for i in range(1, len(A)+1):
312-
for j in range(1, len(B)+1):
313-
if A[i-1] == B[j-1]:
314-
dp[i][j] = dp[i-1][j-1] + 1
315-
result = max(result, dp[i][j])
313+
314+
# 遍历数组 nums1
315+
for i in range(1, len(nums1) + 1):
316+
# 遍历数组 nums2
317+
for j in range(1, len(nums2) + 1):
318+
# 如果 nums1[i-1] 和 nums2[j-1] 相等
319+
if nums1[i - 1] == nums2[j - 1]:
320+
# 在当前位置上的最长公共子数组长度为前一个位置上的长度加一
321+
dp[i][j] = dp[i - 1][j - 1] + 1
322+
# 更新最长公共子数组的长度
323+
if dp[i][j] > result:
324+
result = dp[i][j]
325+
326+
# 返回最长公共子数组的长度
316327
return result
328+
317329
```
318330

319-
> 动态规划:滚动数组
331+
1维DP
320332
```python
321333
class Solution:
322-
def findLength(self, A: List[int], B: List[int]) -> int:
323-
dp = [0] * (len(B) + 1)
334+
def findLength(self, nums1: List[int], nums2: List[int]) -> int:
335+
# 创建一个一维数组 dp,用于存储最长公共子数组的长度
336+
dp = [0] * (len(nums2) + 1)
337+
# 记录最长公共子数组的长度
324338
result = 0
325-
for i in range(1, len(A)+1):
326-
for j in range(len(B), 0, -1):
327-
if A[i-1] == B[j-1]:
328-
dp[j] = dp[j-1] + 1
339+
340+
# 遍历数组 nums1
341+
for i in range(1, len(nums1) + 1):
342+
# 用于保存上一个位置的值
343+
prev = 0
344+
# 遍历数组 nums2
345+
for j in range(1, len(nums2) + 1):
346+
# 保存当前位置的值,因为会在后面被更新
347+
current = dp[j]
348+
# 如果 nums1[i-1] 和 nums2[j-1] 相等
349+
if nums1[i - 1] == nums2[j - 1]:
350+
# 在当前位置上的最长公共子数组长度为上一个位置的长度加一
351+
dp[j] = prev + 1
352+
# 更新最长公共子数组的长度
353+
if dp[j] > result:
354+
result = dp[j]
329355
else:
330-
dp[j] = 0 #注意这里不相等的时候要有赋0的操作
331-
result = max(result, dp[j])
356+
# 如果不相等,将当前位置的值置为零
357+
dp[j] = 0
358+
# 更新 prev 变量为当前位置的值,供下一次迭代使用
359+
prev = current
360+
361+
# 返回最长公共子数组的长度
332362
return result
363+
333364
```
334365

366+
2维DP 扩展
367+
```python
368+
class Solution:
369+
def findLength(self, nums1: List[int], nums2: List[int]) -> int:
370+
# 创建一个二维数组 dp,用于存储最长公共子数组的长度
371+
dp = [[0] * (len(nums2) + 1) for _ in range(len(nums1) + 1)]
372+
# 记录最长公共子数组的长度
373+
result = 0
374+
375+
# 对第一行和第一列进行初始化
376+
for i in range(len(nums1)):
377+
if nums1[i] == nums2[0]:
378+
dp[i + 1][1] = 1
379+
for j in range(len(nums2)):
380+
if nums1[0] == nums2[j]:
381+
dp[1][j + 1] = 1
382+
383+
# 填充dp数组
384+
for i in range(1, len(nums1) + 1):
385+
for j in range(1, len(nums2) + 1):
386+
if nums1[i - 1] == nums2[j - 1]:
387+
# 如果 nums1[i-1] 和 nums2[j-1] 相等,则当前位置的最长公共子数组长度为左上角位置的值加一
388+
dp[i][j] = dp[i - 1][j - 1] + 1
389+
if dp[i][j] > result:
390+
# 更新最长公共子数组的长度
391+
result = dp[i][j]
392+
393+
# 返回最长公共子数组的长度
394+
return result
395+
335396

397+
```
336398
Go:
337399
```Go
338400
func findLength(A []int, B []int) int {

‎problems/1143.最长公共子序列.md‎

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -203,21 +203,49 @@ class Solution {
203203
```
204204

205205
Python:
206-
206+
2维DP
207207
```python
208208
class Solution:
209209
def longestCommonSubsequence(self, text1: str, text2: str) -> int:
210-
len1, len2 = len(text1)+1, len(text2)+1
211-
dp = [[0 for _ in range(len1)] for _ in range(len2)] # 先对dp数组做初始化操作
212-
for i in range(1, len2):
213-
for j in range(1, len1): # 开始列出状态转移方程
214-
if text1[j-1] == text2[i-1]:
215-
dp[i][j] = dp[i-1][j-1]+1
210+
# 创建一个二维数组 dp,用于存储最长公共子序列的长度
211+
dp = [[0] * (len(text2) + 1) for _ in range(len(text1) + 1)]
212+
213+
# 遍历 text1 和 text2,填充 dp 数组
214+
for i in range(1, len(text1) + 1):
215+
for j in range(1, len(text2) + 1):
216+
if text1[i - 1] == text2[j - 1]:
217+
# 如果 text1[i-1] 和 text2[j-1] 相等,则当前位置的最长公共子序列长度为左上角位置的值加一
218+
dp[i][j] = dp[i - 1][j - 1] + 1
216219
else:
217-
dp[i][j] = max(dp[i-1][j], dp[i][j-1])
218-
return dp[-1][-1]
220+
# 如果 text1[i-1] 和 text2[j-1] 不相等,则当前位置的最长公共子序列长度为上方或左方的较大值
221+
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
222+
223+
# 返回最长公共子序列的长度
224+
return dp[len(text1)][len(text2)]
225+
219226
```
227+
1维DP
228+
```python
229+
class Solution:
230+
def longestCommonSubsequence(self, text1: str, text2: str) -> int:
231+
m, n = len(text1), len(text2)
232+
dp = [0] * (n + 1) # 初始化一维DP数组
233+
234+
for i in range(1, m + 1):
235+
prev = 0 # 保存上一个位置的最长公共子序列长度
236+
for j in range(1, n + 1):
237+
curr = dp[j] # 保存当前位置的最长公共子序列长度
238+
if text1[i - 1] == text2[j - 1]:
239+
# 如果当前字符相等,则最长公共子序列长度加一
240+
dp[j] = prev + 1
241+
else:
242+
# 如果当前字符不相等,则选择保留前一个位置的最长公共子序列长度中的较大值
243+
dp[j] = max(dp[j], dp[j - 1])
244+
prev = curr # 更新上一个位置的最长公共子序列长度
245+
246+
return dp[n] # 返回最后一个位置的最长公共子序列长度作为结果
220247

248+
```
221249

222250
Go:
223251
```Go

0 commit comments

Comments
(0)

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