Leetcode - 周赛421

目录

一,3334. 数组的最大因子得分

二,3335. 字符串转换后的长度 I

三,3336. 最大公约数相等的子序列数量

四,3337. 字符串转换后的长度 II


一,3334. 数组的最大因子得分

暴力方法就不演示,这里介绍一个O(n)的做法,前后缀分解,可以预处理nums数组的前缀GCD,LCM和后缀GCD,LCM。然后枚举移除的数,使用前后缀计算总体的GCD和LCM,然后计算出最大值。

代码如下:

class Solution {public long maxScore(int[] nums) {int n = nums.length;long[] sufGcd = new long[n+1];long[] sufLcm = new long[n+1];sufLcm[n] = 1;for(int i=n-1; i>=0; i--){sufGcd[i] = gcd(sufGcd[i+1], nums[i]);sufLcm[i] = lcm(sufLcm[i+1], nums[i]);}long res = sufGcd[0]*sufLcm[0], gc = 0, lc = 1;for(int i=0; i<n; i++){//枚举哪个不选res = Math.max(res, gcd(gc, sufGcd[i+1]) * lcm(lc, sufLcm[i+1]));lc = lcm(lc, nums[i]);gc = gcd(gc, nums[i]);}return res;}long gcd(long x, long y){//(0,x)的最大公约数就是xreturn y==0 ? x : gcd(y, x%y);}long lcm(long x, long y){//(1,x)的最小公倍数就是xreturn x*y/gcd(x, y);}
}

二,3335. 字符串转换后的长度 I

本题有多种做法,这里讲一个简单易懂的,可以发现对于每个字符,它们每次操作产生的字符数量是固定的,所以我们可以先统计26个字符,每个字符的出现次数cnt,然后模拟每次操作所能产生的字符数量,最后cnt数组的和就是答案。

代码如下:

class Solution {int MOD = 1_000_000_007;public int lengthAfterTransformations(String s, int t) {int ans = 0;int[] cnt = new int[26];for(char c : s.toCharArray()){cnt[c-'a']++;}while(t-- > 0){int[] a = cnt.clone();for(int i=1; i<26; i++){a[i] = cnt[i-1]%MOD;}a[0] = cnt[25]%MOD;a[1] = (a[1] + cnt[25])%MOD;cnt = a;}for(int i=0; i<26; i++){ans = (ans + cnt[i])%MOD;}return ans;}
}

三,3336. 最大公约数相等的子序列数量

本题是一道选或不选的问题,分情况讨论,对于第 i 个数:

  • 如果不选,即它既不在seq1中,也不在seq2中,接下来问题变成在第 i+1 个数到第 n-1 个数,有多少种分配使得子序列seq1和seq2的GCD相同
  • 如果选,分两种情况,它被分配到seq1/seq2中,接下来问题变成在第 i+1 个数到第 n-1 个数,有多少种分配使得子序列seq1和seq2的GCD相同

这样就不断的形成子问题,定义dfs(i,j,k):从第 i 个数到第 n-1 个数,且此时seq1的GCD为 j ,seq2的GCD为 k 时,使得子序列seq1和seq2的GCD相同的子序列对的总数。

  • 如果不选,问题变成在第 i+1 个数到第 n-1 个数,有多少种分配使得子序列seq1和seq2的GCD相同,即 dfs(i+1,j,k)
  • 如果选,分两种情况,它被分配到seq1/seq2中,问题变成在第 i+1 个数到第 n-1 个数,有多少种分配使得子序列seq1和seq2的GCD相同,即 dfs(i+1,gcd(j,nums[i]),k) + dfs(i+1, j, gcd(k,nums[i]),nums)
  • 求总对数 dfs(i,j,k) = dfs(i+1,j,k) + dfs(i+1,gcd(j,nums[i]),k) + dfs(i+1, j, gcd(k,nums[i]),nums)

代码如下:

class Solution {int MOD = 1_000_000_007;public int subsequencePairCount(int[] nums) {int n = nums.length;memo = new int[n][201][201];for(int i=0; i<n; i++){for(int[] r : memo[i]){Arrays.fill(r, -1);}}return (dfs(0, 0, 0, nums)-1+MOD)%MOD;//-1是删除全部都不选的情况}int[][][] memo;int dfs(int i, int j, int k, int[] nums){if(i == nums.length) return j == k ? 1 : 0;if(memo[i][j][k] != -1) return memo[i][j][k];long res = (long)dfs(i+1, j, k, nums) + dfs(i+1, gcd(j, nums[i]), k, nums) + dfs(i+1, j, gcd(k, nums[i]), nums);return memo[i][j][k] = (int)(res%MOD);}int gcd(int x, int y){return y==0 ? x : gcd(y, x%y);}
} 

递推写法

class Solution {int MOD = 1_000_000_007;public int subsequencePairCount(int[] nums) {int n = nums.length;int m = 0;for(int x : nums) m = Math.max(x, m);long[][][] f = new long[n+1][m+1][m+1];//f[n][i][i] = 1for(int i=0; i<m+1; i++){f[n][i][i] = 1;}for(int i=n-1; i>=0; i--){for(int j=0; j<m+1; j++){for(int k=0; k<m+1; k++){f[i][j][k] = (f[i+1][j][k] + f[i+1][gcd(j, nums[i])][k] + f[i+1][j][gcd(k, nums[i])])%MOD;}}}return (int)(f[0][0][0]-1+MOD)%MOD;}int gcd(int x, int y){return y==0 ? x : gcd(y, x%y);}
} 

四,3337. 字符串转换后的长度 II

本题与T2不同,对于每个字符,它们操作后会转换成连续的nums[i]个字符,且数据范围更大,无法使用上述做法。这里我们可以使用dfs来预处理每个字符,操作 t 次后,所能形成的字符串长度。

dfs记忆化代码:

class Solution {private static final int MOD = 1_000_000_007;public int lengthAfterTransformations(String s, int t, List<Integer> nums) {int[] cnt = new int[26];for(char x : s.toCharArray()){cnt[x-'a']++;}long ans = 0;memo = new int[t+1][26];for(int i=0; i<t+1; i++) Arrays.fill(memo[i], -1);int[] res = new int[26];for(int i=0; i<26; i++){res[i] = dfs(t, i, nums);ans += ((long)res[i] * cnt[i])%MOD;}return (int)(ans%MOD);}int[][] memo;int dfs(int i, int j, List<Integer> nums){if(i == 0) return 1;if(memo[i][j] != -1) return memo[i][j];long res = 0;for(int x=1; x<=nums.get(j); x++){res = (res + dfs(i-1, (j+x)%26, nums))%MOD;}return memo[i][j] = (int)(res%MOD);}
}

但是上述做法的时间复杂度为O(26*26*t),这肯定会超时间限制,将其转换成dp再来观察观察是否有其他的优化空间(对于本题至少需要一个O(logt)的时间复杂度).

递推代码:

class Solution {private static final int MOD = 1_000_000_007;public int lengthAfterTransformations(String s, int t, List<Integer> nums) {int[] cnt = new int[26];for(char x : s.toCharArray()){cnt[x-'a']++;}long ans = 0;long[][] f = new long[t+1][26];for(int i=0; i<26; i++)f[0][i] = 1;//预处理每个字母处理t次后,字符串的长度//O(26*25*t)for(int i=1; i<t+1; i++){for(int j=0; j<26; j++){for(int x=1; x<=nums.get(j); x++){f[i][j] = (f[i][j] + f[i-1][(j+x)%26])%MOD;}}}//O(1)for(int k=0; k<26; k++){ans += (f[t][k] * cnt[k])%MOD;}return (int)(ans%MOD);}
}

可以发现 f[i][j] = sum(f[i-1][(j+x)%26]),拿示例一举例:

nums = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2]

根据上述公式,可以得到:

将其转换成矩阵的样式:

将 fi0~fi25 矩阵统称为 Fi,那么我们可以得到公式 Fi = M * Fi-1,不断的套用公式,我们可以得到 Fi = M * M * Fi-2 = ... = M^t * F0

这时可以发现,M是一个固定的矩阵(它是通过nums数组计算得来的),M^t 可以使用快速幂来求解,不过这里计算的是矩阵快速幂。

矩阵快速幂优化代码:

class Solution {private static final int MOD = 1_000_000_007;public int lengthAfterTransformations(String s, int t, List<Integer> nums) {int[] cnt = new int[26];for(char x : s.toCharArray()){cnt[x-'a']++;}int[][] m = new int[26][26];for(int i=0; i<26; i++){for(int j=1; j<=nums.get(i); j++){m[i][(i+j)%26]++;}}        int[][] f = new int[26][1];for(int i=0; i<26; i++)f[i][0] = 1;m = pow(m, t, f);long ans = 0;for(int i=0; i<26; i++){System.out.println(cnt[i] + " " + m[i][0]);ans = (ans + (long)cnt[i] * m[i][0])%MOD;}return (int)(ans%MOD);}int[][] pow(int[][] m, int t, int[][] f){int[][] res = f;while(t != 0){if((t&1)!=0){res = mul(m, res);}m = mul(m, m);t >>= 1;}return res;}//矩阵的传参一定要注意:AxB * BxC = AxC !!!int[][] mul(int[][] a, int[][] b){int[][] c = new int[a.length][b[0].length];//c[i][j] += a[i][k] * b[k][j];for(int i=0; i<a.length; i++){for(int k=0; k<a[0].length; k++){if(a[i][k] == 0) continue;for(int j=0; j<b[0].length; j++){c[i][j] = (int)((c[i][j] + (long)a[i][k] * b[k][j])%MOD);}}}return c;}
}

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

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

相关文章

文件管理工具的按路径名称归类功能大公开,将大量文件批量复制或移动到指定路径,办公软件达人的秘密武器

是否还在为成堆的文件归类而苦恼&#xff1f;想要一键就能将海量文件按路径名称轻松归类&#xff0c;无论是复制还是移动&#xff1f;别急&#xff0c;今天就让文件批量改名高手软件的按路径名称归类功能来拯救你的文件管理世界&#xff01;让我们一起告别繁琐&#xff0c;迎接…

建设NFS服务器并实现文件共享

关闭防火墙和s0 systemctl stop firewalld setenforce 0 安装NFS yum install nfs-utils -y 新建共享目录并设置权限 echo "hello" > /nfs/shared/test1 chmod -Rf 777 /nfs/shared/ 配置服务端的NFS配置文件 vim /etc/exports /nfs/shared *(ro) 启动…

曹操出行借助 ApsaraMQ for Kafka Serverless 提升效率,成本节省超 20%

本文整理于 2024 年云栖大会主题演讲《云消息队列 ApsaraMQ Serverless 演进》&#xff0c;杭州优行科技有限公司消息中间件负责人王智洋分享 ApsaraMQ for Kafka Serverless 助力曹操出行实现成本优化和效率提升的实践经验。 曹操出行&#xff1a;科技驱动共享出行未来 曹操…

(转载)Tools for Learning LLVM TableGen

前提 最近在学习有关llvm的东西&#xff0c;其中TableGen占了一部分&#xff0c;所以想特意学习下TableGen相关的语法。这里找到了LLVM官网的一篇介绍TableGen的博客&#xff0c;学习并使用机器翻译为中文。在文章的最后也添加了一些学习TableGen的资源。 原文地址&#xff1…

vue3uniapp实现自定义拱形底部导航栏,解决首次闪烁问题

前言&#xff1a; 我最初在网上翻阅查找了很多方法&#xff0c;发现大家都是说在page.json中tabbar中添加&#xff1a;"custom": true,即可解决首次闪烁的问题&#xff0c;可是添加了我这边还是会闪烁&#xff0c;因此我这边改变了思路&#xff0c;使用了虚拟页面来解…

【P2-5】ESP8266 WIFI模块在AP模式下作为TCP服务器与多个电脑/手机网络助手(TCP客户端)通信——TCP数据透传

前言:完成ESP8266 WIFI模块在AP模式下作为TCP服务器与多个电脑/手机网络助手(TCP客户端)通信——实现TCP数据透传 AP模式,通俗来说模块可以发出一个WIFI热点提供给电脑/手机连接。 TCP服务端,通俗来说就是模块/单片机作为服务器,可以接收多个客户通道的连接。 本…

Kali Linux 新工具推荐: Sploitscan

在 2024.2 版本 Kali Linux 增加了一个新攻击工具: Sploitscan 1.简介: Sploitscan 能够发现操作系统和应用程序中的安全漏洞。 2.特点: 简单的命令行界面 扫描多个操作系统和应用程序 检测多种漏洞 提供详细信息 可定制性强 3.示例: 2024.2 及以后的版本 Kali Linux…

11.Three.js使用indexeddb前端缓存模型优化前端加载效率

11.Three.js使用indexeddb前端缓存模型优化前端加载效率 1.简述 在使用Three.js做数字孪生应用场景时&#xff0c;我们常常需要用到大量模型或数据。在访问我们的数字孪生应用时&#xff0c;每次刷新都需要从web端进行请求大量的模型数据或其他渲染数据等等&#xff0c;会极大…

基于PyTorch的大语言模型微调指南:Torchtune完整教程与代码示例

近年来,大型语言模型(Large Language Models, LLMs)在自然语言处理(Natural Language Processing, NLP)领域取得了显著进展。这些模型通过在大规模文本数据上进行预训练,能够习得语言的基本特征和语义,从而在各种NLP任务上取得了突破性的表现。为了将预训练的LLM应用于特定领域…

探索Unity:从游戏引擎到元宇宙体验,聚焦内容创作

unity是实时3D互动内容创作和运营平台&#xff0c;包括游戏开发、美术、建筑、汽车设计、影视在内的所有创作者&#xff0c;借助Unity将创意变成现实。提供一整套完善的软件解决方案&#xff0c;可用于创作、运营和变现任何实时互动的2D和3D内容&#xff0c;支持平台包括手机、…

3、setup语法糖

setup 概述 setup是Vue3中一个新的配置项&#xff0c;值是一个函数&#xff0c;它是 Composition API 组件中所用到的&#xff1a;数据、方法、计算属性、监视......等等&#xff0c;均配置在setup中。 特点如下&#xff1a; setup函数返回的对象中的内容&#xff0c;可直接…

USB协议学习

文章目录 USB发展背景发展变化速度等级通讯接口 四种传输主设备 & 从设备主设备从设备 连接与检测高速设备与主机连接USB总线常见的几种状态 枚举过程特点 控制传输学习资料 USB发展背景 发展变化 USB1.1&#xff1a;规范了USB低全速传输&#xff1b; USB2.0&#xff1a;…

讲讲 kafka 维护消费状态跟踪的方法?

大家好&#xff0c;我是锋哥。今天分享关于【讲讲 kafka 维护消费状态跟踪的方法&#xff1f;】面试题&#xff1f;希望对大家有帮助&#xff1b; 讲讲 kafka 维护消费状态跟踪的方法&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 Kafka 中&#x…

【成都新篇】龙信科技电子取证实验室,引领科技取证新时代

文章关键词&#xff1a;电子数据取证实验室、手机取证、介质取证、云取证、现场勘查、电子物证 在科技创新的浪潮中&#xff0c;龙信科技成都实验室以其卓越的电子数据取证服务&#xff0c;成为了中西部地区一颗璀璨的明珠。随着新址的搬迁&#xff0c;我们不仅扩大了业务范围…

linux自动清理管理日志文件 logrotate

logrotate是linux通常会自带的工具&#xff0c;可以自动切割清理日志文件 一、安装&#xff08;通常无需&#xff09; 通常系统自带 sudo apt install logrotate或者 sudo dnf install logrotate二、具体使用 以nginx日志为例 1.创建脚本文件 vi /etc/logrotate.d/nginx…

JDBC学习笔记

九月十八: 需要添加jar包到依赖 虽然能驱动了,但是仍然不知道当时为什么不能驱动, 8.0以上会自动驱动, 也就是说只需要做好connection和statement 连接数据库的五种方式: 方式五: Statement: SQL注入小案例: ? 相当于占位符 JDBCUtils: 事务与批处理: String sql "INS…

wps Excel下拉框生成填充及下拉框内容颜色格式修改

一、Excel下拉框生成&#xff1a;(路径&#xff1a;数据-下拉列表) 1、先选中需要插入下拉列表的单元格 2、然后进入“数据-下拉列表”中增加对应的下拉项目(例如&#xff1a;√&#xff0c;X) 二、下拉框选项颜色和字体修改 1、先选中需要修改的下拉列表的所有单元格 2、然…

预约小程序多选修改——思路分享

预约小程序——多选的修改 预约小程序模版的来源&#xff1a;yunzizyy/ZixiAppt: 在这个小程序上做了较多的修改&#xff08;补充了丢失的代码、二维码签到、惩罚封禁机制、多选时间段和设置日期&#xff09;&#xff0c;其中有一个涉及到了时间段选择中的多选功能的添加&…

PostgreSQL核心揭秘(二)-进程和内存架构

目录 1、进程架构2、进程架构图 3、内存架构 4、内存架构图 PostgreSQL 的进程架构采用了一个多进程的设计&#xff0c;这使其能够有效地管理并发连接和资源。以下是 PostgreSQL 的主要进程架构组成部分的详细描述&#xff1a; 1. 主进程&#xff08;Postmaster&#xff09; 功…

pta题目

1.查询至少生产两种不同的计算机(PC或便携式电脑)且机器速度至少为133的厂商 AC: select distinct(pd.maker) --去重查询 from product pd where pd.type in (个人电脑, 便携式电脑) --题目上要求的&#xff0c;至少一个&#xff0c;in是从里面选择 and --这里也是model其实相…