leetcode 404 周赛 找出有效子序列的最大长度 II「暴力」「动态规划」

3202. 找出有效子序列的最大长度 II

题目描述

给你一个整数数组 n u m s nums nums和一个正整数 k k k

n u m s nums nums 的一个子序列 s u b sub sub的长度为 x x x ,如果其满足以下条件,则称其为 有效子序列

( s u b [ 0 ] + s u b [ 1 ] ) % k = = ( s u b [ 1 ] + s u b [ 2 ] ) % k = = . . . = = ( s u b [ x − 2 ] + s u b [ x − 1 ] ) % k (sub[0] + sub[1]) \% k == (sub[1] + sub[2]) \% k == ... == (sub[x - 2] + sub[x - 1]) \% k (sub[0]+sub[1])%k==(sub[1]+sub[2])%k==...==(sub[x2]+sub[x1])%k

返回 n u m s nums nums最长有效子序列 的长度。

数据范围:

  • 2 <= nums.length <= 1 0 3 10^3 103
  • 1 <= nums[i] <= 1 0 7 10^7 107
  • 1 <= k <= 1 0 3 10^3 103

思路1:巧妙的“暴力”

这是我赛时的思路,一种比较巧妙的暴力,就是写起来有点费力

观察数据范围,n和k都是1000,显然正确答案的复杂度应该类似于O(n * k),即1000 * 1000

由于题目的要求:相邻两个数求和对k去模后结果一样,所以我们可以考虑先枚举余数p

此时问题变成了,给定余数 p p p和数组 n u m s nums nums,求一个最长的子序列,满足相邻两项求和模 k k k等于 p p p,此时考虑枚举子序列的起点 n u m s [ i ] nums[i] nums[i],由于余数 p p p是固定的,我们可以求出子序列的下一个数为 ( p − n u m s [ i ] + k ) (p - nums[i] + k)%k (pnums[i]+k),这样我们就不难发现,只要确定了第一个数字和余数p,这条最长的子序列就能确定下来

比如,1 1 2 0 1 1 2 1 2 1 2,假设k是4,当前枚举的余数p是3,只要确定了起点1,那其对应的最长的子序列就是1 2 1 2 1 2 1 2,此时我们需要一种方法可以快速获得下标大于 i i i 的某个特定数的下标,从而实现下标的跳转

虽然 n u m s [ i ] < = 1 e 7 nums[i]<=1e7 nums[i]<=1e7,但是对k取模后,数据范围就变成0到k-1了,所以我们可以考虑开一个vector数组v,对于nums[i]我们在vector数组里存下他的下标,即 v [ n u m s [ i ] % k ] . p u s h _ b a c k ( i ) v[nums[i]\%k].push\_back(i) v[nums[i]%k].push_back(i),然后再搞一个id数组,id[x]代表vector[x]现在用到的下标,这样可以避免重复遍历

我们可以再搞一个vis数组标记一下,因为我们通过跳转得到的一个子序列,从中间的任意一个元素开始跳都不会比起点开始更长,所以标记一下以后这些点就不会再重复计算了,当然还有一种情况是,存在一些中间多余的数字,比如1 1 2 1 1 2 1 2 1 2,最长的序列是1(1) 2 1 (1) 2 1 2 1 2,中间的两个1在跳转的过程中不会被遍历到,vis也不会标记它,此时id[1]和id[2]的位置也已经到了最后面,理论上从它开始跳转根本不会按正常的跳转方式得到一个完整的子序列,这种情况下是否会影响答案呢?

答案是不会影响的,看刚刚的例子,被省略的两个1,前面已经存在过1了,以1开头最长的子序列长度已经确定了,其他的1再开始也不会比他更长,所以是不会影响答案

不难发现,第二层看上去虽然是一层for一层while,但其实每个点只访问了一次,所以是O(n)的,所以这个代码的复杂度是O(n * k)

class Solution {
public:int maximumLength(vector<int>& nums, int k) {int tr[1005];int n = nums.size();vector<int>v[1005];for(int i = 1; i <= n; ++i){tr[i] = nums[i - 1];tr[i] %= k;v[tr[i]].push_back(i);}int ans = 0;for(int p = 0; p < k; ++p){//枚举余数bool vis[1005];memset(vis, 0, sizeof(vis));int id[1005];memset(id, 0, sizeof(id));for(int i = 1; i <= n; ++i){//枚举起点if(vis[i])continue;vis[i] = 1;int num = 1;int a = tr[i];int pos = i;while(1){int b = (p - a + k) % k;while(id[b] < v[b].size()){if(v[b][id[b]] <= pos){++id[b];}else break;}if(id[b] < v[b].size() && v[b][id[b]] > pos){pos = v[b][id[b]];vis[pos] = 1;++num;a = b;}else break;}ans = max(ans, num);}}return ans;}
};

思路2:dp

确定了余数p和第一个数,这个序列就确定了,会是两个数字循环

所以我们可以考虑用 d p [ n u m [ i ] ] dp[num[i]] dp[num[i]]表示以 n u m [ i ] num[i] num[i] 结尾的子序列的最长长度

转移方程很简单, d p [ n u m s [ i ] ] = d p [ ( p − n u m s [ i ] + k ) dp[nums[i]] = dp[(p - nums[i] + k) % k] + 1 dp[nums[i]]=dp[(pnums[i]+k)

class Solution {
public:int maximumLength(vector<int>& nums, int k) {int ans = 0;for(int p = 0; p < k; ++p){vector<int>dp(k, 0);for(int i = 0; i < nums.size(); ++i){nums[i] %= k;dp[nums[i]] = dp[(p - nums[i] + k) % k] + 1;ans = max(ans, dp[nums[i]]);}}return ans;}
};

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

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

相关文章

如何通过TPM活动提升员工的设备管理能力?

在快节奏的现代职场中&#xff0c;设备管理能力已成为员工综合素质的重要一环。然而&#xff0c;如何有效提升这一能力&#xff0c;让员工在设备操作、维护和管理上更加得心应手呢&#xff1f;答案就隐藏在TPM&#xff08;Total Productive Maintenance&#xff0c;全面生产维护…

Python容器 之 列表--定义

1.什么是列表呢&#xff1f; 列表(list)是 Python 中使用最频繁的数据类型, 在其他语言中通常叫做数组, 专门用来存储一组数据 列表,list, 使用 [ ] 列表可以存放任意多个数据 列表中可以存放任意类型的数据 列表中数据之间 使用 逗号隔开 2.列表如何定义&#xff1f; &#…

【TB作品】atmega16 计算器,ATMEGA16单片机,Proteus仿真

实验报告&#xff1a;基于ATmega16单片机的简易计算器设计 1. 实验背景 计算器是日常生活和工作中不可或缺的工具&#xff0c;通过按键输入即可实现基本的四则运算。通过本实验&#xff0c;我们将利用ATmega16单片机、矩阵键盘和LCD1602显示屏&#xff0c;设计并实现一个简易…

Lua协程介绍

Lua协程 协程什么是协程协程的特点协程和线程的区别协程的工作原理 Lua协程示例 协程 什么是协程 协程&#xff08;coroutine&#xff09;是一种程序组件&#xff0c;它允许执行代码在不同的点暂停和恢复&#xff0c;从而实现协作式的多任务处理。与传统的线程不同&#xff0c…

2023软考中级《软件设计师》(备考冲刺版) | 数据库系统

目录 1.数据库的基本概念 1.1 数据库体系结构 1.2 三级模式结构 1.3 数据仓库 2.数据库设计过程 2.1 概念结构设计 2.1.1 概念设计过程 2.1.2 E-R图 2.2 逻辑结构设计 2.2.1 关系模式相关概念 2.2.2 E-R图转关系模式&#xff08;涉及下午题&#xff09; 2.2.3 关系…

小白学习手册:轻松理解MQ消息队列

目录 # 开篇 RabbitMQ介绍 通讯概念 1. 初始MQ及类型 2. MQ的架构 2.1 RabbitMQ的结构和概念 2.2 RabbitMQ消息流示意图 3. MQ下载使用 3.1 Docker下载MQ参考 3.2 进入RabbitMQ # 开篇 MessagesQueue 是一个抽象概念&#xff0c;用于描述消息队列系统的一般特性和功能…

python如何求不定积分

sympy介绍 sympy库的安装非常的简单&#xff0c;利用conda命令可以快速的完成安装。 conda install sympy 接下来&#xff0c;我们将介绍利用第三方库sympy来完成积分的计算。 python求解不定积分 接下来&#xff0c;我们将介绍上述的不定积分的求解。 首先导入sympy库中的…

如何应对情绪和培养理性的书

以下是几本关于如何应对情绪和培养理性的书籍推荐&#xff1a; 《情绪智商》&#xff08;Emotional Intelligence&#xff09; - 丹尼尔戈尔曼&#xff08;Daniel Goleman&#xff09; 这本书探讨了情绪智商&#xff08;EQ&#xff09;的重要性以及如何通过提高EQ来改善个人和职…

大聪明教你学Java | 深入浅出聊 RocketMQ

前言 &#x1f34a;作者简介&#xff1a; 不肯过江东丶&#xff0c;一个来自二线城市的程序员&#xff0c;致力于用“猥琐”办法解决繁琐问题&#xff0c;让复杂的问题变得通俗易懂。 &#x1f34a;支持作者&#xff1a; 点赞&#x1f44d;、关注&#x1f496;、留言&#x1f4…

3201. 找出有效子序列的最大长度 I

Powered by:NEFU AB-IN Link 文章目录 3201. 找出有效子序列的最大长度 I题意思路代码拓展 3201. 找出有效子序列的最大长度 I 题意 给你一个整数数组 nums。 nums 的子序列 sub 的长度为 x &#xff0c;如果其满足以下条件&#xff0c;则称其为 有效子序列&#xff1a; (…

concurrent.futures模块中ThreadPoolExecutor用法

ThreadPoolExecutor 是 Python 的 concurrent.futures 模块中的一个类&#xff0c;用于并发执行多个任务。通过使用线程池&#xff0c;它允许你将任务分配给池中的线程来执行&#xff0c;而不是每次需要执行任务时都创建新线程。这种方式可以显著提高性能和效率&#xff0c;特别…

YOLOv10改进教程|C2f-CIB加入注意力机制

一、 导读 论文链接&#xff1a;https://arxiv.org/abs/2311.11587 代码链接&#xff1a;GitHub - CV-ZhangXin/AKConv YOLOv10训练、验证及推理教程 二、 C2f-CIB加入注意力机制 2.1 复制代码 打开ultralytics->nn->modules->block.py文件&#xff0c;复制SE注意力机…

Docker期末复习

云计算服务类型有: IaaS 基础设施及服务 PaaS 平台及服务 SaaS 软件及服务 服务类型辨析示例: IaaS 服务提供的云服务器软件到操作系统,具体应用软件自己安装,如腾讯云上申请的云服务器等;SaaS提供的服务就是具体的软件,例如微软的Office套件等。 云计算部署模式有: 私有云…

Rust学习笔记 (命令行命令) : 用override set 设置工具链

在cargo run某个项目时出现了如下错误&#xff1a;error: failed to run custom build command for ring v0.16.20&#xff08;无法运行“Ring v0.16.20”的自定义构建命令&#xff09;&#xff0c;在PowerShell命令行运行命令 rustup override set stable-msvc后成功运行。 o…

发那科机床采集数据

前面两篇重点介绍了理论&#xff0c;从这篇开始&#xff0c;我们开始进行实战。首先从发那科机床开始&#xff0c;为何第一个将发那科。因为发那科系统机床有三最。最广泛&#xff08;中国保有量最多&#xff09;、 最多资料&#xff08;发那科系统的开发包历史悠久&#xff0c…

Linux——移动文件或目录,查找文件,which命令

移动文件或目录 作用 - mv命令用于剪切或重命名文件 格式 bash mv [选项] 源文件名称 目标文件名称 注意 - 剪切操作不同于复制操作&#xff0c;因为它会把源文件删除掉&#xff0c;只保留剪切后的文件。 - 如果在同一个目录中将某个文件剪切后还粘贴到当前目录下&#xff0c;…

CS144 Lab3 TCPSender复盘

一.基础概念 1.TCPSender在TCPSocket中的地位与作用 Lab0中实现了基于内存模拟的流控制-字节流&#xff08;ByteStream&#xff09;&#xff0c;底层使用std::deque实现&#xff0c;根据最大容量Capacity进行容量控制。个人理解它相当于应用层的输入输出缓存区&#xff0c;用户…

江协科技51单片机学习- p23 DS1302实时时钟

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…

巴比达内网穿透:深度剖析其在解决远程连接挑战中的技术优势

在信息技术日新月异的今天&#xff0c;远程协作与管理的需求日益增长&#xff0c;但内网环境的隔离性一直是横亘在高效远程操作面前的一道坎。本文将深入探讨一款专为打破此壁垒而生的工具——巴比达内网穿透&#xff0c;如何以其技术创新和高效性能&#xff0c;成为解决远程连…

汽车内饰塑料件光照老化实验箱

塑料件光照老化实验箱概述 塑料件光照老化实验箱&#xff0c;又称为氙灯老化试验箱&#xff0c;是一种模拟自然光照条件下塑料材料老化情况的实验设备。它通过内置的氙灯或其他光源&#xff0c;产生接近自然光的紫外线辐射&#xff0c;以此来加速塑料及其他材料的光老化过程。…