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.rhkb.cn/news/463189.html

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

相关文章

【java】java的基本程序设计结构06-运算符

运算符 一、分类 算术运算符关系运算符位运算符逻辑运算符赋值运算符其他运算符 1.1 算术运算符 操作符描述例子加法 - 相加运算符两侧的值A B 等于 30-减法 - 左操作数减去右操作数A – B 等于 -10*乘法 - 相乘操作符两侧的值A * B等于200/除法 - 左操作数除以右操作数B /…

群控系统服务端开发模式-应用开发-菜单功能开发

为什么优先开发菜单&#xff0c;而不是优先开发管理员&#xff1f;查看一下程序草图就明白&#xff0c;还有一个重点就是&#xff0c;管理员需要添加图片&#xff0c;而我还没有封装上传工具及上传目标。 一、添加路由 在根目录下route文件夹下的app.php文件里面&#xff0c;添…

顶点动画-河流的效果

目标是让一个矩形网格面片&#xff0c;通过顶点动画&#xff0c;实现出河流的效果。&#xff08;如下图&#xff09;所谓的河流效果&#xff0c;就是呈现出波浪感&#xff0c;而想要呈现出波浪感&#xff0c;我们必须了解 波长、波动频率、波动幅度 这些关键因素 1、波浪感的关…

线程函数和线程启动的几种不同形式

线程函数和线程启动的几种不同形式 在C中&#xff0c;线程函数和线程启动可以通过多种形式实现。以下是几种常见的形式&#xff0c;并附有相应的示例代码。 1. 使用函数指针启动线程 最基本的方式是使用函数指针来启动线程。 示例代码&#xff1a; #include <iostream&g…

3.1 快速启动Flink集群

文章目录 1. 环境配置2. 本地启动3. 集群启动4. 向集群提交作业4.1 提交作业概述4.2 添加打包插件4.3 将项目打包4.4 在Web UI上提交作业4.5 命令行提交作业 在本实战中&#xff0c;我们将快速启动Apache Flink 1.13.0集群&#xff0c;并在Hadoop集群环境中提交作业。首先&…

讲讲RabbitMQ 性能优化

大家好&#xff0c;我是锋哥。今天分享关于【RabbitMQ 性能优化&#xff1f;】面试题。希望对大家有帮助&#xff1b; 讲讲RabbitMQ 性能优化 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 RabbitMQ 是一个强大的消息代理&#xff0c;广泛用于分布式系统中&#x…

redolog与binlog的写入机制

redo log 事务在执行的过程中&#xff0c;生成的redo log是要先写到redo log buffer中的。redo log buffer里面的内容不需要每次生成后都直接持久化到磁盘。 如果事务执行期间MySQL发生异常重启&#xff0c;那这部分日志就丢了&#xff0c;但是由于没有commit&#xff0c;所以…

推荐一款数学绘图工具:FX Draw Tools

FX Draw Tools是目前最新好用的一款数学绘图工具。该软件界面简洁&#xff0c;使用方便。该软件能够帮助用户快速制作数学图表&#xff0c;从而提高用户的工作效率&#xff0c;轻松完成制图工作&#xff0c;欢迎需要的用户前来下载使用。 功能特色 1. 180和360可以被添加到任何…

《云计算网络技术与应用》实训8-1:OpenvSwitch简单配置练习

1.按《云计算网络技术与应用》实训5-1进行环境配置&#xff0c;安装好OVS 2.开启OVS虚拟交换机 3.创建一个网桥br0 4.查看网桥列表 5.把ens34网卡连接到网桥br0上 6. 查看网桥br0所有端口 7.列出网卡ens34连接的所有网桥列表 8.查看OVS网络状态 9.将网桥br0上连接的网卡ens34删…

Netty 组件介绍 - pipeline

ChannelPipeline为ChannelHandler链提供了容器&#xff0c;并且定义了该链上的入站和出站事件。当initChannel()被调用时&#xff0c;ChannelInitializer将在ChannelPipeline中安装一组自定义的ChannelHandler。他们的执行顺序就是添加顺序。 Server public class Server {pr…

Leetcode 热题100 之 二叉树3

1.二叉树展开为链表 思路分析&#xff1a;迭代法。对于每个节点&#xff0c;我们将其左子树放到右子树的位置。将原来的右子树接到新的右子树&#xff08;也就是原来的左子树&#xff09;的末端。移动到右子节点&#xff0c;继续处理下一节点&#xff0c;直到所有节点都处理完。…

UE5.4 PCG Layered Biomes插件

B站学习链接 官方文档 一、PCGSpawn Preset&#xff1a;负责管理PCG要用到的植被资产有哪些 二、BiomesSettings&#xff1a;设置要使用的植被资产Layer、Spawn参数 1.高度Layer参数&#xff1a; 2.地形Layer&#xff1a;我这里用地形样条线绘制了一块地形Layer 绘制点和…

单个相机矫正畸变

1、通过标定助手获取到内参外参&#xff0c;外参在此无效&#xff0c;只用到了内参 2、然后通过halcon算子进行矫正 参考&#xff1a;超人视觉

Orleans8.2入门测试

微软官方文档&#xff1a;快速入门&#xff1a;使用 ASP.NET Core 生成第一个 Orleans 应用 - .NET | Microsoft Learn 项目及引入的nuget库&#xff1a; 1、接口项目&#xff1b;2、接口实现项目&#xff1b;3、silo项目&#xff1b;4、客户端项目 其中Microsoft.Orleans.St…

电赛入门之软件stm32keil+cubemx

hal库可以帮我们一键生成许多基本配置&#xff0c;就不需要自己写了&#xff0c;用多了hal库就会发现原来用基本库的时候都过的什么苦日子&#xff08;笑 下面我们以f103c8t6&#xff0c;也就是经典的最小核心板来演示 一、配置工程 首先来新建一个工程 这里我们配置rcc和sys&…

第三十章 章节练习商品列表组件封装

目录 一、需求说明 二、技术要点 三、完整代码 3.1. main.js 3.2. App.vue 3.3. MyTable.vue 3.4. MyTag.vue 一、需求说明 1. my-tag 标签组件封装 (1) 双击显示输入框&#xff0c;输入框获取焦点 (2) 失去焦点&#xff0c;隐藏输入框 (3) 回显标签信息 (4) 内…

vue 快速入门

文章目录 一、插值表达式 {{}}二、Vue 指令2.1 v-text 和 v-html&#xff1a;2.2 v-if 和 v-show&#xff1a;2.3 v-on&#xff1a;2.4 v-bind 和 v-model&#xff1a;2.5 v-for&#xff1a; 三、生命周期四、Vue 组件库 Element五、Vue 路由 本文章适用于后端人员&#xff0c;…

数据建模圣经|数据模型资源手册卷2,探索数据库逻辑模型设计

在企业信息系统体系结构中&#xff0c;数据处于核心地位。数据模型是信息系统开发和应用的基本指南&#xff0c;在逻辑模型层面为数据在数据库中的存储提供蓝图&#xff0c;以及对宏观世界的抽象设计。 简介 《The Data Model Resource Book, Revised Edition, Volume2》&#…

形态学操作篇 原理公式代码齐活

一、腐蚀 腐蚀操作的核心原理是利用一个结构元素在图像上进行扫描&#xff0c;判断结构元素所覆盖的区域与前景像素的关系。如果结构元素完全被包含在前景像素区域内&#xff0c;那么结构元素中心对应的像素位置在腐蚀后的图像中被标记为前景像素&#xff1b;如果结构元素不完…

Unity引擎材质球残留贴图引用的处理

大家好&#xff0c;我是阿赵。   这次来分享一下Unity引擎材质球残留贴图引用的处理 一、 问题 在使用Unity调整美术效果的时候&#xff0c;我们很经常会有这样的操作&#xff0c;比如&#xff1a; 1、 同一个材质球切换不同的Shader、 比如我现在有2个Shader&#xff0c;…