C++ 子序列

news2024/9/25 19:23:14

目录

最长递增子序列 

 摆动序列

 最长递增子序列的个数

 最长数对链

 最长定差子序列

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

 最长等差数列

等差数列划分 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.coloradmin.cn/o/1533727.html

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

相关文章

带你学会深度学习之卷积神经网络[CNN] - 4

前言 本文不讲述如泛化&#xff0c;前向后向传播&#xff0c;过拟合等基础概念。 本文图片来源于网络&#xff0c;图片所有者可以随时联系笔者删除。 本文提供代码不代表该神经网络的全部实现&#xff0c;只是为了方便展示此模型的关键结构。 CNN&#xff0c;常用于计算机视…

OSM欧诗漫加入美妆可持续联盟,共话绿色发展新路径

3月12日&#xff0c;中国化妆品行业首个可持续联盟——美妆可持续联盟&#xff08;BSC&#xff09;正式宣告成立。作为国内珍珠科技美肤领军品牌&#xff0c;OSM欧诗漫受邀成为可持续发展联盟的首批成员&#xff0c;并在第46个植树节之际&#xff0c;与80余家中外同行企业携手种…

rfc793-timewait状态

time wait状态 主动关闭连接的一方&#xff0c;在四次挥手最后一次发送 ACK 后&#xff0c;进入 TIME_WAIT 状态。在这个状态里&#xff0c;主动关闭连接一方等待 2MSL&#xff08;Maximum Segment Life&#xff0c;报文段最大生存时间&#xff0c;在RFC793 中定义为 2 min&…

表情识别数据集

表情视频数据集 在许多的研究中,研究者通常会把人脸表情识别区分为静态的人脸表情识别(static facial emotion recognition)和动态的人脸表情识别(dynamic facial emotion recognition)。前者希望通过单张图片辨别人的表情从而达到识别人情绪的目的,而后者希望感知视频/…

docker一键部署若依前后端分离版本

比如这里把文件放到/xin/docker/jiaoZ/的目录下&#xff0c;jar包和下面的配置文件都放在这个文件夹下。 注意要把jar端口改为你实际启动的&#xff0c;映射端口也可以改为你想要的。 这里的映射端口为&#xff1a;nginx监听80端口&#xff0c;jar在8620端口&#xff0c;mysq…

java并发编程之 volatile关键字

1、简单介绍一下JMM Java 内存模型&#xff08;Java Memory Model 简称JMM&#xff09;是一种抽象的概念&#xff0c;并不真实存在&#xff0c;指一组规则或规范&#xff0c;通过这组规范定义了程序中各个变量的访问方式。java内存模型(JMM)屏蔽掉各种硬件和操作系统的内存访问…

C语言每日一题06

一、题目 二、解析 void main &#xff08;&#xff09; { char c1&#xff0c;c2&#xff1b; int a1&#xff0c;a2&#xff1b; c1 getchar &#xff08;&#xff09;&#xff1b;//读取第一个输入&#xff0c;c11 scanf &#xff08;“%3d”&#xff0c;&a1&#xff…

Python螺旋折线蓝桥杯(来源lanqiao.cn 题目176) 时间超限

题目描述 如图所示的螺旋折线经过平面上所有整点恰好一次。 对于整点(X, Y)&#xff0c;我们定义它到原点的距离dis(X, Y)是从原点到(X, Y)的螺旋折线段的长度。 例如dis(0, 1)3, dis(-2, -1)9 给出整点坐标(X, Y)&#xff0c;你能计算出dis(X, Y)吗&#xff1f; 输入格式 …

MySQL--Buffer Pool

虽然说 MySQL 的数据是存储在磁盘里的&#xff0c;但是也不能每次都从磁盘里面读取数据&#xff0c;这样性能是极差的。为此&#xff0c;Innodb 存储引擎设计了一个缓冲池&#xff08;Buffer Pool&#xff09;&#xff0c;来提高数据库的读写性能。 有了缓冲池后&#xff1a; …

Linux系统本地部署Docker Compose UI服务结合内网穿透实现公网访问

文章目录 1. 安装Docker2. 检查本地docker环境3. 安装cpolar内网穿透4. 使用固定二级子域名地址远程访问 Docker Compose UI是Docker Compose的web界面。这个项目的目标是在Docker Compose之上提供一个最小的HTTP API&#xff0c;同时保持与Docker Compose CLI的完全互操作性。…

如何在CentOS搭建docker compose ui可视化工具并无公网IP远程管理容器

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

谷歌Gemma大模型部署记录

谷歌Gemma大模型部署记录 配置信息 1.系统&#xff1a;Ubuntu20 2.显卡&#xff1a;RTX3060 6G 一、安装Ollama 官网地址&#xff1a;https://ollama.com/download/linux 按照指令安装 curl -fsSL https://ollama.com/install.sh | sh二、运行模型 输入指令&#xff1a;…

ubuntu中截圖工具

文章目录 一、flameshot1、安裝指令2、延遲截圖 二、总结 github社區 參考1 參考二 一、flameshot 1、安裝指令 sudo apt install flameshot如果想要把此時的照片復制下來&#xff0c;點擊從右數第六個圖標 2、延遲截圖 flameshot gui -d 3000二、 总结

使用腾讯云轻量应用服务器怎么搭建网站?

2024年腾讯云轻量应用服务器搭建网站教程&#xff0c;建站大全&#xff0c;包括WordPress建站、宝塔面板安装、Typecho博客搭建、LAMP、LNMP、Node.js、ASP.NET、Docker、K3s、WooCommerce、互动直播后台搭建、SRS音视频服务器、Matomo网站数据统计等网站搭建教程&#xff0c;腾…

【JS】浅谈Promise

Promise 前言一、Promise是什么&#xff1f;二、为什么用Promise&#xff1f;2.1解决回调地狱2.2 集中错误处理2.3代码解耦和复用 三、做什么&#xff1f;四、原型方法和实例方法&#xff1f;五、应用场景&#xff1f; 前言 promise是es6的新规范&#xff0c;它是一种异步解决…

【漏洞复现】6.Struts2 S2-061 远程命令执行漏洞(CVE-2020-17530)复现与分析

文章目录 1. 预备知识2. 漏洞复现2.1 漏洞介绍2.2 漏洞原理分析2.2.1 Apache Struts2架构2.2.2 OGNL语法介绍2.2.3漏洞原理 2.3 漏洞复现2.3.1 靶场搭建2.3.2 漏洞探测2.3.3 漏洞利用2.3.4 POC分析 2.4 漏洞修复 1. 预备知识 Struts是一个用于开发Java EE网络应用程序的开放源代…

2024年03月 Discourse 3.3.0.beta1 版本的更新

在这个版本的更新中 Discourse 完成了 Ember 5 版本的升级和更新。 Ember.js是一个用于创建 web 应用的 开源JavaScript MVC 框架&#xff0c;采用基于字符串的Handlebars 模板&#xff0c;支持双向绑定、观察者模式、计算属性&#xff08;依赖其他属性动态变化&#xff09;、…

扩展以太网(数据链路层)

目录 一、在物理层扩展以太网 二、在数据链路层扩展以太网 三、以太网交换机的特点 四、以太网交换机的交换方式 五、以太网交换机的自学习功能 六、小结 一、在物理层扩展以太网 使用光纤扩展&#xff1a; • 主机使用光纤&#xff08;通常是一对光纤&#xff09;和…

C语言基础知识点(十八)联合、

【C语言】联合体-共用体 &#xff08;union&#xff09; 详解-阿里云开发者社区 (aliyun.com) 联合 在C语言中是一种数据类型&#xff0c;能在同一个内存空间中存储不同的数据类型&#xff08;不是同时储存&#xff09;。 典型用法&#xff1a;设计一种表以存储及无规律、实…

Redis相关操作大全一篇全搞定

Redis是单线程吗? Redis 的单线程主要是指 Redis 的网络 10 和键值对读写是由一个线程来完成的&#xff0c;这也是 Redis 对外提供键值存储服务的主要流程。但Redis 的其他功能&#xff0c;比如持久化、异步删除、集群数据同步等&#xff0c;其实是由额外的线程执行的。 Redi…