在计算机科学中,动态规划是解决许多优化问题的强大工具。最长递增子序列问题是一个经典示例,它不仅展示了动态规划的基本思想,还引导我们思考如何优化算法。本文将详细探讨这一问题的基本思路及其实现方法,提供 Python 和 C++ 的解决方案,并对算法进行深入分析。

给定一个整数数组 nums,找出其中最长的递增子序列的长度。递增子序列是指从数组中选出的一个子序列,其中的元素按顺序排列并且毎个元素都大于前一个元素。
nums 中的一个子序列,使得这个子序列的元素严格递增,且其长度最大。 为以
结尾的最长递增子序列的长度。
,我们可以通过查看它前面的所有元素
来更新
,如果
,那么可以将
加入到以
结尾的子序列中。因此,递推关系为:
dp ,长度与 nums 相同,所有元素初始为 1 ,因为每个元素自身可以形成一个子序列。nums, 更新 dp 数组: i 从 1 到 n-1 ( n 为 nums 的长度)。j从 0 到 i-1, 更新 dp[i] 。max(dp) ,即为最长递增子序列的长度。。
tails,其中 tails[k] 存储当前长度为 k+1 的递增子序列的末尾元素的最小值。对于每个 num,可以使用二分育找确定它在 tails 中的位置,从而更新 tails。 的方法,可以用 bisect 库来实现高效的二分查找,优化子序列的构建过程。
,适用于较小规模的问题。
,适用于更大规模的输入。
以上就是最长递增子序列问题的基本思路。
class Solution:
def lengthOfLIS(self, nums):
if not nums:
return 0
dp = [1] * len(nums) # 初始化 dp 数组
for i in range(1, len(nums)): # 外层循环
for j in range(i): # 内层循环
if nums[j] < nums[i]: # 如果找到较小的元素
dp[i] = max(dp[i], dp[j] + 1) # 更新 dp[i]
return max(dp) # 返回最长递增子序列的长度dp 向量,长度与 nums 相同,所有值为 1。dp 数组。class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
if (nums.empty()) return 0;
vector<int> dp(nums.size(), 1); // 初始化 dp 数组
for (int i = 1; i < nums.size(); i++) { // 外层循环
for (int j = 0; j < i; j++) { // 内层循环
if (nums[j] < nums[i]) { // 如果找到较小的元素
dp[i] = max(dp[i], dp[j] + 1); // 更新 dp[i]
}
}
}
return *max_element(dp.begin(), dp.end()); // 返回最长递增子序列的长度
}
};dp 向量,长度与 nums 相同,所有值为 1。dp 向量。max_element 函数获取 dp 中的最大值,代表最长递增子序列的长度。