【C++动态规划 最长公共子序列】1035. 不相交的线|1805

【C++动态规划 最长公共子序列】1035. 不相交的线|1805

本文涉及知识点

C++动态规划

LeetCode1035. 不相交的线

在两条独立的水平线上按给定的顺序写下 nums1 和 nums2 中的整数。
现在,可以绘制一些连接两个数字 nums1[i] 和 nums2[j] 的直线,这些直线需要同时满足:
nums1[i] == nums2[j]
且绘制的直线不与任何其他连线(非水平线)相交。
请注意,连线即使在端点也不能相交:每个数字只能属于一条连线。
以这种方法绘制线条,并返回可以绘制的最大连线数。
示例 1:

在这里插入图片描述

输入:nums1 = [1,4,2], nums2 = [1,2,4]
输出:2
解释:可以画出两条不交叉的线,如上图所示。
但无法画出第三条不相交的直线,因为从 nums1[1]=4 到 nums2[2]=4 的直线将与从 nums1[2]=2 到 nums2[1]=2 的直线相交。
示例 2:
输入:nums1 = [2,5,1,2,5], nums2 = [10,5,2,1,5,2]
输出:3
示例 3:
输入:nums1 = [1,3,7,1,7,5], nums2 = [1,9,2,5,1]
输出:2
提示:
1 <= nums1.length, nums2.length <= 500
1 <= nums1[i], nums2[j] <= 2000

# 动态规划的状态

性质一:令连线(i,j)在nums1的下标是i,nums2的下标是j。则两条连线(i1,j1),(i2,j2),其中i1 < i2,则j1 < j2,否则会交叉。
性质二:我们将各线按i的升序排序排序,根据性质一,则j也是升序。
性质三:令某最优解是{KaTeX parse error: Undefined control sequence: \cdost at position 1: \̲c̲d̲o̲s̲t̲(i1,j1)、(i2,j2)、(i3,j3)KaTeX parse error: Undefined control sequence: \cdost at position 1: \̲c̲d̲o̲s̲t̲}。如果存在j1<j4<j2,则将j2换成j4也是最优解。

动态规划的状态表示

dp[i][j]表示,所有线的上端点下标 <= i,下端下标<=j,且最后一条连线的下端点下标是j。dp[i][j] = -n-1表示不存在的可能。下标从1开始。空间复杂度:O(nm)

动态规矩的转移方程+双指针

dp[i+1] = dp[i] 没有选择上端点i。
nums[j1] == nums[i] 且j1 > j 且j1最小,如果存在合法的j1,则j1 = m
MaxSelf(dp[i+1][j1+1] , dp[i][j]+1)
时间复杂度:O(nm)

动态规划的填表顺序

枚举前置状态
for(i = 0 To n-1) j = 0 To m-1

动态规划的初始化

dp[0][0]=0,其它全为-n-1

动态规划的返回值

max(dp.back())

代码

核心代码

classSolution{public:intmaxUncrossedLines(vector<int>& nums1, vector<int>& nums2){constint N = nums1.size();constint M = nums2.size(); vector<vector<int>>dp(N +1, vector<int>(M +1,-N-1)); dp[0][0]=0;for(int i =0; i < N; i++){ dp[i +1]= dp[i];for(int j =0,j1=0; j < M; j++){while((j1 < M)&&((nums2[j1]!= nums1[i])||(j1 < j))){ j1++;}if(j1 >= M)continue; dp[i +1][j1 +1]=max(dp[i +1][j1 +1], dp[i][j]+1);}}return*max_element(dp.back().begin(), dp.back().end());}};

单元测试

vector<int> nums1, nums2;TEST_METHOD(TestMethod1){ nums1 ={1,4,2}, nums2 ={1,2,4};auto res =Solution().maxUncrossedLines(nums1, nums2);AssertEx(2, res);}TEST_METHOD(TestMethod12){ nums1 ={2,5,1,2,5}, nums2 ={10,5,2,1,5,2};auto res =Solution().maxUncrossedLines(nums1, nums2);AssertEx(3, res);}TEST_METHOD(TestMethod13){ nums1 ={1,3,7,1,7,5}, nums2 ={1,9,2,5,1};auto res =Solution().maxUncrossedLines(nums1, nums2);AssertEx(2, res);}

扩展阅读

我想对大家说的话
工作中遇到的问题,可以按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。
学习算法:按章节学习《喜缺全书算法册》,大量的题目和测试用例,打包下载。重视操作
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注
闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛
失败+反思=成功 成功+反思=成功

视频课程

先学简单的课程,请移步ZEEKLOG学院,听白银讲师(也就是鄙人)的讲解。
https://edu.ZEEKLOG.net/course/detail/38771
如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.ZEEKLOG.net/lecturer/6176

测试环境

操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。

Read more

Java 部署:Tomcat 集群部署(负载均衡 + 会话共享)

Java 部署:Tomcat 集群部署(负载均衡 + 会话共享)

👋 大家好,欢迎来到我的技术博客! 📚 在这里,我会分享学习笔记、实战经验与技术思考,力求用简单的方式讲清楚复杂的问题。 🎯 本文将围绕Java部署这个话题展开,希望能为你带来一些启发或实用的参考。 🌱 无论你是刚入门的新手,还是正在进阶的开发者,希望你都能有所收获! 文章目录 * Java 部署:Tomcat 集群部署(负载均衡 + 会话共享) 🚀 * 一、为什么需要 Tomcat 集群?🤔 * 二、架构设计概览 🏗️ * 三、环境准备 🛠️ * 1. 软件版本要求 * 2. 服务器规划(以 3 节点为例) * 四、部署 Tomcat 节点 🖥️ * 1. 安装 Tomcat * 2. 配置 server.xml(关键!) * 3. 部署测试应用 * 五、配置 Nginx

By Ne0inhk
微服务学习笔记(2)——SpringCloud Nacos

微服务学习笔记(2)——SpringCloud Nacos

🔥我的主页:九转苍翎⭐️个人专栏:《Java SE 》《Java集合框架系统精讲》《MySQL高手之路:从基础到高阶 》《计算机网络 》《Java工程师核心能力体系构建》《RabbitMQ理论与实践》天行健,君子以自强不息。 0.前言 * SpringBoot版本:3.2.5 * SpringCloud版本:2023.0.3 * SpringCloud Alibaba版本:2023.0.1.0 * nacos版本:2.2.3(已免费上传至我的资源) * 项目源码:spring-cloud-blog 1.概述 Nacos(Dynamic Naming and Configuration Service)是阿里巴巴开源的一个更易于构建云原生应用的动态服务发现、配置和管理平台。在 Spring Cloud 体系中,

By Ne0inhk
RustFS快速上手指南:3种部署方式任选,10分钟搞定高性能对象存储

RustFS快速上手指南:3种部署方式任选,10分钟搞定高性能对象存储

2025年,当对象存储成为云原生应用标配时,RustFS凭借其惊人的性能表现和Apache 2.0开源许可迅速崛起。本文为你揭秘三种实战部署方案,助你快速搭建企业级存储服务。 目录 一、RustFS核心优势速览 二、环境准备(通用步骤) 2.1 系统要求 2.2 防火墙配置 三、方案一:Docker部署(推荐新手) 3.1 快速启动 3.2 Docker Compose方式(生产推荐) 四、方案二:单机二进制部署(最简依赖) 4.1 下载安装 4.2 创建配置文件 4.3 创建系统服务 五、方案三:Kubernetes部署(云原生方案) 5.1

By Ne0inhk