C++ 子序列

目录

最长递增子序列 

 摆动序列

 最长递增子序列的个数

 最长数对链

 最长定差子序列

 最长的斐波那契子序列的长度

 最长等差数列

等差数列划分 II - 子序列 


最长递增子序列 

300. 最长递增子序列

 子数组是连续的,子序列可以不连续,那么就要去[0, i - 1] 区间找

参考代码

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

 摆动序列

 376. 摆动序列

错误: g[i] = max(g[i], f[j] + 1);这个地方写错成f[i],导致逻辑错误

参考代码

class Solution {
public:int wiggleMaxLength(vector<int>& nums) {int n = nums.size();vector<int> f(n, 1), g(n, 1);int ret = 1;for(int i = 1; i < n; i++){for(int j = 0; j < i; j++){if(nums[j] < nums[i]) f[i] = max(f[i], g[j] + 1);else if(nums[j] > nums[i]) g[i] = max(g[i], f[j] + 1);}ret = max(ret, max(f[i], g[i]));}return ret;}
};

 最长递增子序列的个数

673. 最长递增子序列的个数 ☆☆☆☆☆

逻辑其实差不多,我们需要用len来更新count,如果只表示一个count的话没有len,没法更新count;只有在nums[j] < nums[i] 的时候才能操作,这是递增的基本条件;然后通过长度来更新;大于自然要重置,等于则延续count[j];通过for j 循环找出 i 位置为结尾的最长长度和最大个数

参考代码

class Solution {
public:int findNumberOfLIS(vector<int>& nums) {int n = nums.size();vector<int> len(n, 1), count(n, 1);int maxlen = 1, retcount = 1;for(int i = 1; i < n; i++){for(int j = 0; j < i; j++){if(nums[j] < nums[i]){if(len[j] + 1 == len[i]) count[i] += count[j];else if(len[j] + 1 > len[i])len[i] = len[j] + 1, count[i] = count[j];}}if(len[i] > maxlen)maxlen = len[i], retcount = count[i];else if(len[i] == maxlen)retcount += count[i];}return retcount;}
};

 最长数对链

646. 最长数对链

 去[0,  i - 1] 里面找符合条件的,再比较

参考代码

class Solution {
public:int findLongestChain(vector<vector<int>>& pairs) {int n = pairs.size();sort(pairs.begin(), pairs.end());vector<int> dp(n, 1);int ret = 1;for(int i = 1; i < n; i++){for(int j = 0; j < i; j++){if(pairs[j][1] < pairs[i][0])dp[i] = max(dp[i], dp[j] + 1);}ret = max(ret, dp[i]);}return ret;}
};

 最长定差子序列

1218. 最长定差子序列

 最开始,老样子n方,但是发现超时;

class Solution5_1 {
public:int longestSubsequence(vector<int>& arr, int difference) {int n = arr.size();vector<int> dp(n, 1);int ret = 1;for (int i = 1; i < n; i++){for (int j = 0; j < i; j++){if (arr[j] + difference == arr[i]) dp[i] = max(dp[i], dp[j] + 1);}ret = max(ret, dp[i]);}return ret;}
};

然后发现只要找最后一个倒找,找到最后一个满足差值的就行;后面才发现,如果一个数据很长而且都满足条件的很少,那么这个时候优化就没有用了,

class Solution5_2 {
public:int longestSubsequence(vector<int>& arr, int difference) {int n = arr.size();vector<int> dp(n, 1);int ret = 1;for (int i = 1; i < n; i++){for (int j = i - 1; j >= 0; j--){if (arr[j] + difference == arr[i]){dp[i] = dp[j] + 1;break;}}ret = max(ret, dp[i]);}return ret;}
};

 所以我们采用hash<元素, 满足条件的个数>来映射

参考代码

class Solution {
public:int longestSubsequence(vector<int>& arr, int difference) {unordered_map<int, int> hash;int n = arr.size(), ret = 1;hash[arr[0]] = 1;for(int i = 1; i < n; i++){hash[arr[i]] = hash[arr[i] - difference] + 1;ret = max(ret, hash[arr[i]]);}return ret;}
};

 最长的斐波那契子序列的长度

873. 最长的斐波那契子序列的长度

 如果是一维的状态表示:以i位置为结尾的最长斐波那契序列的长度,那么它的更新条件就要前面两个数,又要遍历两遍,但也不对,没法通过前面的状态来改变当前位置的状态;

所以用结尾两个位置来锁定这个斐波那契序列;自然就是二维dp

且是严格递增,hash可以直接全写出来(也可以一步一步定义),且是<int , int> 每个元素只有一个对应的下标

注意:最后一步 oj题没有这时候只会报错,

参考代码

class Solution {
public:int lenLongestFibSubseq(vector<int>& arr) {int n = arr.size();vector<vector<int>> dp(n, vector<int>(n, 2));unordered_map<int, int> hash;for(int i = 0; i < n; i++)hash[arr[i]] = i;int ret = 2;for(int j = 2; j < n; j++){for(int i = 1; i < j; i++){int num = arr[j] - arr[i];if(hash.count(num) && hash[num] < i)dp[i][j] = dp[hash[num]][i] + 1;ret = max(ret, dp[i][j]);}}return ret < 3 ? 0 : ret;}
};

一步步定义参考代码 

class Solution {
public:int lenLongestFibSubseq(vector<int>& arr) {int n = arr.size();vector<vector<int>> dp(n, vector<int>(n, 2));unordered_map<int, int> hash;// for(int i = 0; i < n; i++)//     hash[arr[i]] = i;hash[arr[0]] = 0;int ret = 2;for (int i = 1; i < n - 1; i++){for (int j = i + 1; j < n; j++){int num = arr[j] - arr[i];if (hash.count(num) && hash[num] < i)dp[i][j] = dp[hash[num]][i] + 1;ret = max(ret, dp[i][j]);}hash[arr[i]] = i;}return ret < 3 ? 0 : ret;}
};

 最长等差数列

1027. 最长等差数列

 

以为我们需要元素对应的下标,所以用哈希表,

第二,这题并不是严格递增,那就是很可能会有相同的数,如果一次定义完哈希值,那么相同元素的下标就会用后面的那个,但是也可以定义为<int, vector<int>>

其三:每一次的 i  j 结尾都是不同的,所以ret必须要放在第二层循环里

注意 ret = 2, 题目是length >= 2 ,且两个数也被认为是构成等差数列

代码如下

class Solution {
public:int longestArithSeqLength(vector<int>& nums) {int n = nums.size();vector<vector<int>> dp(n, vector<int>(n, 2));int ret = 2;unordered_map<int, vector<int>> hash;for(int i = 0; i < n; i++)hash[nums[i]].push_back(i);for(int j = 2; j < n; j++){for(int i = 1; i < j; i++){int num = 2 * nums[i] - nums[j];// if(hash.count(num) && hash[num] < i)//不能这么写了因为hash[num]是vector<int>if(hash.count(num))for(auto e : hash[num])if(e < i)dp[i][j] = max(dp[i][j], dp[e][i] + 1);ret = max(ret, dp[i][j]);}}return ret;}
};

 和 -> 最长定差子序列 想法类似,num只要找最接近 i 的就行,可以理解为覆盖掉原来的距离 i 较远元素的下标

参考代码

class Solution {
public:int longestArithSeqLength(vector<int>& nums) {int n = nums.size();vector<vector<int>> dp(n, vector<int>(n, 2));int ret = 2;unordered_map<int, int> hash;hash[nums[0]] = 0;for(int i = 1; i < n - 1; i++){for(int j = i + 1; j < n; j++){int num = 2 * nums[i] - nums[j];if(hash.count(num) && hash[num] < i)dp[i][j] = dp[hash[num]][i] + 1;ret = max(ret, dp[i][j]);}hash[nums[i]] = i;}return ret;}
};

等差数列划分 II - 子序列 

 446. 等差数列划分 II - 子序列

 

 思路: 题目求的是个数,那么dp表要初始化成0,既然是子序列  个数 那么就是满足条件的所有下标(e),这里不能覆盖下标,要找到所有下标,所以hash是int 和vector<int> 对应,

两个i  j   for的顺序只对覆盖hash有影响作用

参考代码

class Solution {
public:int numberOfArithmeticSlices(vector<int>& nums) {int n = nums.size();vector<vector<int>> dp(n, vector<int>(n));unordered_map<long long, vector<int>> hash;for(int i = 0; i < n; i++)hash[nums[i]].push_back(i);int ret = 0;for(int i = 1; i < n - 1; i++){for(int j = i + 1; j < n; j++){long long num = (long long)2 * nums[i] - nums[j];if(hash.count(num))for(auto e : hash[num])if(e < i)dp[i][j] += dp[e][i] + 1;ret += dp[i][j];}}return ret;}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/760280.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【CKA模拟题】掌握Pod日志输出的秘密

题干 For this question, please set this context (In exam, diff cluster name) 对于这个问题&#xff0c;请设置这个上下文(在考试中&#xff0c;diff cluster name) kubectl config use-context kubernetes-adminkubernetes product pod is running. when you access log…

【算法刷题day1】Leetcode:704. 二分查找、27. 移除元素

Leetcode 704&#xff1a;标准二分查找 文档讲解&#xff1a;代码随想录 题目链接&#xff1a;704.二分查找 状态&#xff1a;稳定输出 题目&#xff1a; 给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nums 和一个目标值 target &#xff0c;写一个函数搜索 n…

在Linux环境底下 用C语言执行Python程序

在Linux环境底下 用C语言执行Python程序 文章目录 在Linux环境底下 用C语言执行Python程序1、环境安装&检测2、C语言调用Python语句2.1 直接调用python语句2.2 调用无参python函数2.3 调用有参python函数 1、环境安装&检测 通过C语言调用Python代码&#xff0c;需要先安…

springboot企业级抽奖项目业务二(用户模块)

书接上回&#xff0c;梅开二度 开发流程 该业务基于rouyi生成好了mapper和service的代码&#xff0c;现在需要在controller层写接口 实际操作流程&#xff1a; 看接口文档一>controller里定义函数一>看给出的工具类一>补全controller里的函数一>运行测试 接口…

【数据结构】堆和树详解堆和二叉树的实现堆的top-k问题

主页&#xff1a;醋溜马桶圈-CSDN博客 专栏&#xff1a;数据结构_醋溜马桶圈的博客-CSDN博客 gitee&#xff1a;mnxcc (mnxcc) - Gitee.com 目录 1.树概念及结构 1.1 树的概念 2.2 树的相关概念 1.3 树的表示 1.4 树在实际中的运用 2.二叉树的概念及结构 2.1 二叉树的概念…

vue前端解析jwt

vue前端解析jwt 我们可以用在线解析看解析的结果&#xff1a;https://www.lddgo.net/encrypt/jwt-decrypt 但是如果在前端需要解析token&#xff0c;拿到其中的权限信息&#xff0c;可以这样解决。 在线的&#xff1a; 完美解决&#xff1a; 代码&#xff1a; function par…

MySQL | 表的约束

目录 1. 空属性 NULL 2. 默认值 DEFAULT 3. 列描述comment 4. zerofill 5. 主键 PRIMARY KEY 6. 自增长AUTO_INCREMENT 7. 唯一键UNIQUE 8. 外键 真正约束字段的是数据类型&#xff0c;但是数据类型约束很单一&#xff0c;需要有一些额外的约束&#xff0c;更好的保证数…

web前端常用标签(html)

1.定义 1.1标签 语法规范&#xff1a;<标签名 属性名"属性值">标签名</标签名> 标签之间可以嵌套 1.2属性 定制元素的行为的。属性是不通用的&#xff0c;每一个标签存在自身的属性。当属性名属性值时&#xff0c;可以只写属性值 2.HTML常用标签 2…

面试笔记——Redis(分布式锁的使用场景及实现原理)

分布式锁的使用场景 资源竞争控制&#xff1a;多个客户端同时访问共享资源时&#xff0c;可以使用分布式锁来控制资源的并发访问&#xff0c;防止多个客户端同时对同一资源进行修改造成数据不一致的问题。 避免重复操作&#xff1a;在分布式环境中&#xff0c;可能会出现多个客…

如何实现手机遥控端关机按钮同时关闭TV端和手机端界面

目前家庭电视机主要通过其自带的遥控器进行操控&#xff0c;实现的功能较为单一。例如&#xff0c;当我们要在TV端搜索节目时&#xff0c;电视机在遥控器的操控下往往只能完成一些字母或数字的输入&#xff0c;而无法输入其他复杂的内容。分布式遥控器将手机的输入能力和电视遥…

基于springboot+vue的智慧生活商城系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

Pytest自动化测试执行环境切换的两种解决方案(超详细)

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 痛点分析 在实际企业的项目中&#xff0c;自动化测试的代码往往需要在不同的环境中进行切换&am…

【STL基础】vector、stack、queue、list、pair、map、unordered_map、set、unordered_set(详细讲解)

vector、list、pair、unordered_map、unordered_set、stack、queue 参考文章&#xff1a; &#xff08;1&#xff09;【apollo】泛型编程 与 STL &#xff08;2&#xff09;c stack用法 入门必看 超详细 &#xff08;3&#xff09;C中queue的用法&#xff08;超详细&#xff0c…

C语言关于void类型的指针作为函数形参在使用时需要注意的坑

目录 前言 一、void*指针使用时不同编译器下的处理结果 二、void*指针传递的指针变量进行位运算时&#xff0c;一定要注意强制转换的类型&#xff0c;和值的取值范围 总结 前言 众所周知&#xff0c;void* 指针作为函数形参时&#xff0c;表示可以接受任意类型的参数&#xf…

C语言基础知识点(十七)结构体中只用指针来存储字符串

// 如果需要用结构存储字符串&#xff0c;用字符数组作为成员会比较简单 // 如果需要使用指向char的指针来进行存储&#xff0c;那么需要请求malloc来 // 为字符串分配合适的存储空间#include <stdio.h> #include <string.h> //提供strcpy()\strlen()的原型 #i…

基于FFmpeg混流及录制rtmp直播流

1、什么是混流&#xff1f; 混流就是把多路音视频流合成单流。准确的说&#xff0c;混流应该叫做混音&#xff08;音频流&#xff09;混画面&#xff08;视频流&#xff09; 混流的过程包括解码、混流、编码和推流四个部分。混流这个环节包括做抖动缓冲&#xff0c;目的是把多…

GDPU Java 天码行空4

文章目录 一、实验目的二、实验内容及要求三、实验内容及要求1. 设计AnimalTool工具类&#xff0c;实现eat()函数多态性&#x1f496; AnimalDemo.java&#x1f338; 运行结果 2. 是猫是狗&#x1f496; DuoTaiDemo5.java&#x1f338; 运行结果 3. 太会了&#x1f496; DuoTai…

国内IP地址切换排行榜软件大全

随着互联网的飞速发展&#xff0c;IP地址切换技术在日常工作和生活中扮演着越来越重要的角色。无论是为了网络安全、访问特定地区网站&#xff0c;还是进行市场调研、网络爬虫等&#xff0c;IP地址切换都成为了不可或缺的工具。虎观代理将为您介绍国内较受欢迎的IP地址切换软件…

B004-springcloud alibaba 服务容错 Sentinel

目录 高并发带来的问题服务雪崩效应常见容错方案常见的容错思路隔离超时限流熔断降级 常见的容错组件 Sentinel入门什么是Sentinel微服务项目集成Sentinel核心库安装Sentinel控制台实现一个接口的限流 Sentinel的概念和功能基本概念重要功能 Sentinel规则流控规则三种流控模式三…

深度学习——线性代数相关知识

线性代数基础知识 一、线性代数基础知识1、标量2、向量3、矩阵4、张量5、点积6、向量—矩阵积7、矩阵—矩阵乘法 二、小结 一、线性代数基础知识 本节将介绍简要地回顾一下部分基本线性代数内容&#xff0c;线性代数中的基本数学对象、算术和运算&#xff0c;并用数学符号和相…