当前位置:实例文章 » 其他实例» [文章]代码随想录算法学习心得 45 | 300.最长递增子序列、674.最长连续递增序列、718.最长重复子数组...

代码随想录算法学习心得 45 | 300.最长递增子序列、674.最长连续递增序列、718.最长重复子数组...

发布人:shili8 发布时间:2024-12-22 02:36 阅读次数:0

**代码随想录算法学习心得45**

在本篇文章中,我们将讨论四个经典的动态规划问题:最长递增子序列(Longest Increasing Subsequence, LIS)、最长连续递增序列(Longest Continuous Increasing Sequence, LCIS)、最长重复子数组(Longest Repeated Subarray, LRS)和最长公共子序列(Longest Common Subsequence, LCS)。这些问题都是经典的动态规划问题,能够帮助我们提高对算法设计和实现的理解。

### 最长递增子序列 (LIS)

给定一个整数数组 `nums`,要求找到其中最长的递增子序列。例如,如果输入 `[10,9,2,5,3,7,101,18]`,输出应该是 `[2,3,7,101]`。

#### 动态规划解决方案我们可以使用动态规划来解决这个问题。具体来说,我们将维护一个长度为 `n` 的数组 `dp`,其中 `dp[i]` 表示序列 `nums[0..i-1]` 中最长递增子序列的长度。

def longest_increasing_sequence(nums):
 n = len(nums)
 dp = [1] * n for i in range(1, n):
 for j in range(i):
 if nums[i] > nums[j]:
 dp[i] = max(dp[i], dp[j] +1)

 return max(dp)


#### 时间复杂度分析时间复杂度为 O(n^2),因为我们需要对每个元素进行 O(n) 次比较。

### 最长连续递增序列 (LCIS)

给定一个整数数组 `nums`,要求找到其中最长的连续递增子序列。例如,如果输入 `[1,3,5,7]`,输出应该是 `[1,3,5,7]`。

#### 动态规划解决方案我们可以使用动态规划来解决这个问题。具体来说,我们将维护一个长度为 `n` 的数组 `dp`,其中 `dp[i]` 表示序列 `nums[0..i-1]` 中最长连续递增子序列的长度。

def longest_continuous_increasing_sequence(nums):
 n = len(nums)
 dp = [1] * n for i in range(1, n):
 if nums[i] > nums[i -1]:
 dp[i] = dp[i -1] +1 return max(dp)


#### 时间复杂度分析时间复杂度为 O(n),因为我们只需要对每个元素进行一次比较。

### 最长重复子数组 (LRS)

给定两个整数数组 `nums1` 和 `nums2`,要求找到其中最长的重复子数组。例如,如果输入 `[1,2,3]` 和 `[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25]`,输出应该是 `[1,2,3]`。

#### 动态规划解决方案我们可以使用动态规划来解决这个问题。具体来说,我们将维护两个长度为 `n` 的数组 `dp1` 和 `dp2`,其中 `dp1[i]` 表示序列 `nums1[0..i-1]` 中最长重复子数组的长度,`dp2[j]` 表示序列 `nums2[0..j-1]` 中最长重复子数组的长度。

def longest_repeated_subarray(nums1, nums2):
 n = len(nums1)
 m = len(nums2)

 dp1 = [0] * (n +1)
 dp2 = [0] * (m +1)

 for i in range(1, n +1):
 for j in range(1, m +1):
 if nums1[i -1] == nums2[j -1]:
 dp1[i] = max(dp1[i], dp2[j] +1)
 dp2[j] = max(dp2[j], dp1[i])

 return max(max(dp1), max(dp2))


#### 时间复杂度分析时间复杂度为 O(n * m),因为我们需要对每个元素进行 O(m) 次比较。

### 最长公共子序列 (LCS)

给定两个整数数组 `nums1` 和 `nums2`,要求找到其中最长的公共子序列。例如,如果输入 `[1,2,3]` 和 `[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25]`,输出应该是 `[1,2,3]`。

#### 动态规划解决方案我们可以使用动态规划来解决这个问题。具体来说,我们将维护两个长度为 `n` 的数组 `dp1` 和 `dp2`,其中 `dp1[i]` 表示序列 `nums1[0..i-1]` 中最长公共子序列的长度,`dp2[j]` 表示序列 `nums2[0..j-1]` 中最长公共子序列的长度。

def longest_common_subsequence(nums1, nums2):
 n = len(nums1)
 m = len(nums2)

 dp1 = [0] * (n +1)
 dp2 = [0] * (m +1)

 for i in range(1, n +1):
 for j in range(1, m +1):
 if nums1[i -1] == nums2[j -1]:
 dp1[i] = max(dp1[i], dp2[j] +1)
 dp2[j] = max(dp2[j], dp1[i])

 return max(max(dp1), max(dp2))


#### 时间复杂度分析时间复杂度为 O(n * m),因为我们需要对每个元素进行 O(m) 次比较。

综上所述,我们可以使用动态规划来解决最长递增子序列、最长连续递增序列、最长重复子数组和最长公共子序列等问题。这些问题都是经典的动态规划问题,能够帮助我们提高对算法设计和实现的理解。

**参考资料**

* 《算法导论》第三版* 《数据结构与算法分析》第二版

其他信息

其他资源

Top