欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > IT业 > Leetcode 300. 最长递增子序列 记忆化搜索、贪心二分 C++实现

Leetcode 300. 最长递增子序列 记忆化搜索、贪心二分 C++实现

2025/5/29 23:37:18 来源:https://blog.csdn.net/2301_77329667/article/details/141955689  浏览:    关键词:Leetcode 300. 最长递增子序列 记忆化搜索、贪心二分 C++实现

Leetcode 300. 最长递增子序列

问题:给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。

子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。

算法1:记忆化搜索

        创建一维数组 memo 并赋初始值为 0 ,表示没有被计算过。

        进入 dfs 函数。从后往前递归,如果满足前面字母比后面字母小,那么进行下一层递归(向前)更新 memo 。

        在函数的最后返回值时,要重新遍历递归的原因是:函数 dfs 传入的参数是子序列末尾数字的位置,末尾数字已经定了,所以要遍历一遍。

代码:

class Solution {
public:int lengthOfLIS(vector<int>& nums) {int n = nums.size();if(n == 0)  return 0;vector<int> memo(n);auto dfs = [&](auto &&dfs,int i){int &res = memo[i];if(res) return res;// 被计算过for(int j = 0;j < i;j++)if(nums[j] < nums[i])   res = max(dfs(dfs,j),res);return ++res;};int ans = 0;for(int i = 0;i < n;i++)  ans = max(ans,dfs(dfs,i));return ans;}
};

算法2:1:1翻译成递推

代码:

class Solution {
public:int lengthOfLIS(vector<int>& nums) {int n = nums.size();if(n == 0)  return 0;vector<int> memo(n);for(int i = 0;i < n;i++){memo[i] = 0;for(int j = 0;j < i;j++)if(nums[j] < nums[i])   memo[i] = max(memo[i],memo[j]);memo[i]++;}return ranges::max(memo);}
};

算法3:贪心 + 二分查找

        遍历 nums 数组,使用二分查找方法找到在 g 数组中,所遍历到的元素应该存放的位置,利用 lower_bound( ) 函数。如果在 g 数组的中间找到应该存放的位置,就替换掉这个元素(注意是替换不是插入)。替换掉这个元素后,数组 g 的长度保持不变,除非后续遍历能够完全覆盖数组 g 后面的数字,也就是记录了之前最长子序列长度。

lower_bound( ) : 返回指向第一个值不小于 val 的位置,也就是返回第一个大于等于 val 值的位置。(通过二分查找)。

        

代码:

class Solution {
public:int lengthOfLIS(vector<int> &nums) {vector<int> g;for (int x : nums){// 遍历nums数组auto it = ranges::lower_bound(g, x);//在g中找到可以插入x的位置。前提是有序的情况下if (it == g.end())  g.push_back(x); // 如果这个位置在末尾,则添加到g的尾部else    *it = x;//否则替换掉那个位置的元素}return g.size();}
};

算法4:原地修改

        在 算法3 的基础上,取消数组 g 的使用,改为原地修改,即在遍历 nums 数组的过程中,如果符合条件,则将其填入对应位置,按照上一方法的思路,如果是在数组最后添加元素,则填完元素后让 end 指针向后移动一位。

代码:

class Solution {
public:int lengthOfLIS(vector<int> &nums) {auto end = nums.begin();for (int x : nums){auto it = lower_bound(nums.begin(), end, x);*it = x;if (it == end)  end++;}return end - nums.begin();}
};

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词