LeetCode --- 421周赛

题目列表

3334. 数组的最大因子得分

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

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

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

一、数组的最大因子得分

数据范围足够小,可以用暴力枚举移除的数字,得到答案,时间复杂度为O(n^2),代码如下

class Solution {
public:long long maxScore(vector<int>& nums) {int n = nums.size();auto get = [&](int i)->long long{// gcd(0, x) = x, lcm(1, x) = xlong long x = 0; // 计算 gcdlong long y = 1; // 计算 lcmfor(int j = 0; j < n; j++){if(i == j) continue;x = gcd(x, nums[j]);y = lcm(y, nums[j]);}return x * y;};long long ans = get(-1); // 不去除任何数字for(int i = 0; i < n; i++){ans = max(ans, get(i));}return ans;}
};

有没有更快的做法?我们同样枚举被移除的数字,有没有方法能更加快速的算出剩余数字的 LCM 和 GCD?有的,只要我们提前算出左右两个部分的 LCM 和 GCD,就能直接计算得出剩余部分的LCM 和 GCD,即进行前后缀分解,时间复杂度为O(n),代码如下

注意:上面的时间复杂度默认 LCM 和 GCD 是O(1),但实际上 GCD/LCM 的时间复杂度为O(logn)

class Solution {
public:long long maxScore(vector<int>& nums) {int n = nums.size();vector<long long> suf_gcd(n + 1), suf_lcm(n + 1, 1);// gcd(0, x) = x, lcm(1, x) = xfor(int i = n - 1; i >= 0; i--){suf_gcd[i] = gcd(suf_gcd[i + 1], nums[i]);suf_lcm[i] = lcm(suf_lcm[i + 1], nums[i]);}long long ans = suf_gcd[0] * suf_lcm[0]; // 不去除任何数long long pre_gcd = 0, pre_lcm = 1;for(int i = 0; i < n; i++){ // 同时计算 ans 和 前缀gcd/lcmans = max(ans, gcd(pre_gcd, suf_gcd[i + 1]) * lcm(pre_lcm, suf_lcm[i+1]));pre_gcd = gcd(pre_gcd, nums[i]);pre_lcm = lcm(pre_lcm, nums[i]);}return ans;}
};

二、字符串转换后的长度 I

这题的数据范围比较小,我们可以模拟 t 次转换的过程。对于任意一个字母,它的转换规则是一样的,所以我们先统计出 26 个字母出现的次数,然后根据规则,进行转换即可,代码如下

class Solution {const int MOD = 1e9 + 7;
public:int lengthAfterTransformations(string s, int t) {vector<int> cnt(26);for(auto e : s) cnt[e - 'a']++;while(t--){vector<int>tmp(26);for(int i = 0; i < 26; i++)tmp[i] = cnt[(i-1+26)%26]; // 如'a'的出现次数变成'b'的出现次数// 'z' 不仅能变成 'a' , 还能变成 'b'tmp[1] =(tmp[1] + cnt[25]) % MOD;swap(tmp, cnt);}int ans = 0;for(int i = 0; i < 26; i++) ans = (ans + cnt[i]) % MOD;return ans;}
};

但是一旦 t 的范围过大,就会超时,有没什么更快的方法?由于每个字母的转移方式是固定的,所以只要给定一个字母和操作次数就能得到一个长度,问题是如何加速这个计算过程?

假设f[i][j]表示字母 i (用0-25表示) 经过 j 次操作的长度,我们有如下方程

代码如下

class Solution {const int MOD = 1e9 + 7;// 矩阵快速幂vector<vector<int>> POW(vector<vector<int>> a, int n){int m = a.size();vector<vector<int>> res(m, vector<int>(m));for(int i = 0; i < m; i++) res[i][i] = 1;while(n){if(n & 1) res = mul(res, a);a = mul(a, a);n >>= 1;}return res;}// 矩阵相乘vector<vector<int>> mul(const vector<vector<int>>& a, const vector<vector<int>>& b){int n = a.size(), m = b[0].size();vector<vector<int>> c(n, vector<int>(m));for(int i = 0; i < n; i++){for(int k = 0; k < n; k++){if(a[i][k] == 0) continue;for(int j = 0; j < m; j++){c[i][j] = (c[i][j] + 1LL * a[i][k] * b[k][j]) % MOD;}}}return c;}
public:int lengthAfterTransformations(string s, int t) {int n = s.size();vector<vector<int>> mtx(26, vector<int>(26));for(int i = 0; i < 26; i++){mtx[i][(i+1)%26] = 1;}mtx[25][1] = 1;auto f = POW(mtx, t); // 矩阵的t次幂vector<int> cnt(26);for(auto e : s) cnt[e - 'a']++;long long ans = 0;for(int i = 0; i < 26; i++){ans += reduce(f[i].begin(), f[i].end(), 0LL) * cnt[i];}return ans % MOD;}
};

三、最大公约数相等的子序列数量

对于每一个数,都有三种可能,要么在seq1,要么在seq2,要么不选,一旦我们选择完一个数,对于剩下的数,我们依旧可以用相同的方法进行处理,大问题被划分为一个个小问题,进行解决。

设dfs(i,j,k)表示当seq1的gcd=j,seq2的gcd=k时,从前 i 个数中进行选择能得到的合法方案数

对于 nums[i]

  • 1、不选,方案数为 dfs(i-1,j,k)
  • 2、选入seq1,方案数为 dfs(i-1,gcd(j,nums[i]),k)
  • 3、选入seq2,方案数为 dfs(i-1,j,gcd(k,nums[i])) 

故状态转换方程为

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])) 

边界条件:当 i < 0 时,返回 j == k,表示将所有的数都进行分配后,如果seq1的gcd = seq2的gcd,则为一种合法方案数

代码如下

class Solution {const int MOD = 1e9 + 7;
public:int subsequencePairCount(vector<int>& nums) {int n = nums.size();int memo[n][201][201];memset(memo, -1, sizeof(memo));function<int(int,int,int)> dfs = [&](int i, int j, int k)->int{if(i < 0) return j == k;if(memo[i][j][k] != -1) return memo[i][j][k];int res = dfs(i - 1, j, k); // 不选res = (res + dfs(i - 1, gcd(j, nums[i]), k)) % MOD;res = (res + dfs(i - 1, j, gcd(k, nums[i]))) % MOD;return memo[i][j][k] = res;};// 注意我们的dfs会包含一种seq1和seq2都为空的方案,需要被减去// 由于取模操作 dfs(n - 1, 0, 0) - 1 可能为负数,所以要 + MOD) % MODreturn (dfs(n - 1, 0, 0) - 1 + MOD) % MOD;}
};

四、字符串转换后的长度 II

这题的思路同第二题,只是计算的矩阵不同,具体代码如下

class Solution {const int MOD = 1e9 + 7;// 矩阵快速幂vector<vector<int>> POW(vector<vector<int>> a, int n){int m = a.size();vector<vector<int>> res(m, vector<int>(m));for(int i = 0; i < m; i++) res[i][i] = 1;while(n){if(n & 1) res = mul(res, a);a = mul(a, a);n >>= 1;}return res;}// 矩阵相乘vector<vector<int>> mul(const vector<vector<int>>& a, const vector<vector<int>>& b){int n = a.size(), m = b[0].size();vector<vector<int>> c(n, vector<int>(m));for(int i = 0; i < n; i++){for(int k = 0; k < n; k++){if(a[i][k] == 0) continue;for(int j = 0; j < m; j++){c[i][j] = (c[i][j] + 1LL * a[i][k] * b[k][j]) % MOD;}}}return c;}
public:int lengthAfterTransformations(string s, int t, vector<int>& nums) {int n = s.size();vector<vector<int>> mtx(26, vector<int>(26));for(int i = 0; i < 26; i++){for(int j = i + 1; j <= i + nums[i]; j++){mtx[i][j%26] = 1;}}auto f = POW(mtx, t);vector<int> cnt(26);for(auto e : s) cnt[e - 'a']++;long long ans = 0;for(int i = 0; i < 26; i++){ans += reduce(f[i].begin(), f[i].end(), 0LL) * cnt[i];}return ans % MOD;}
};

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

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

相关文章

动态规划-回文串问题——5.最长回文子串

1.题目解析 题目来源&#xff1a;5.最长回文子串——力扣 测试用例 2.算法原理 1.状态表示 判断回文子串需要知道该回文子串的首尾下标&#xff0c;所以需要一个二维数组且数据类型为bool类型来存储每个子字符串是否为回文子串&#xff0c; 即dp[i][j]:以第i个位置为起始&a…

微积分复习笔记 Calculus Volume 1 - 4.4 The Mean Value Theorem

4.4 The Mean Value Theorem - Calculus Volume 1 | OpenStax

docker engine stopped

1&#xff09;环境&#xff1a;win 10 2&#xff09;docker安装时已经已经安装了虚拟机 3&#xff09;启用网络适配器 4&#xff09;启用docker服务&#xff08;依赖服务LanmanServer&#xff09; 5&#xff09;全都弄好了&#xff0c;docker还是打不开&#xff0c;没办法了&a…

【VM实战】VMware迁移到VirtualBox

VMware 虚拟机开机卸载VMware Tools 调整虚拟磁盘 对于Windows 10及以上的虚拟机&#xff0c;一般VMware默认都会选Nvme固态硬盘。在导出前必须将其改为SATA&#xff0c;否则VirtualBox导入会报Appliance Import错误 (E_INVALIDARG 0x80070057) 先删掉当前盘的挂载&#xff…

某本书上的一张序列图评点

贝贝 2019-8-24 10:56 潘老师&#xff0c;这个图是不是不太对。插卡&#xff0c;输入密码并不是ATM的职责&#xff1f; UMLChina潘加宇: 这种图用建模思维一挤压&#xff0c;脓包太多了。 问题一、几个生命线上的实例&#xff0c;抽象级别不一致。 ATM用户--系统&#xff0…

Docker | 校园网上docker pull或者docker run失败的一种解决方法

场景 需要从仓库拉取镜像 无论使用命令docker pull 还是 docker run 但是总是显示如下的错误: 解决方法 查看虚拟机网络连接方式 Linux上检查校园网是否登录 有界面 无界面 只是命令行操作的Linux 关于Linux服务器端更新命令apt update没有效果问题总结(校园网认证)

推荐一款功能强大的AI实时变声器:FliFlik Voice Changer

FliFlik VoiCE Changer是一款专注于声音变换与音频处理的创新软件&#xff0c;旨在满足从日常娱乐、游戏直播到播客制作、专业音频编辑的多种应用场景需求。无论是想在游戏中变换声音逗乐队友&#xff0c;还是在播客中塑造个性化的音效&#xff0c;这款软件都能提供灵活而强大的…

YOLOv8改进,YOLOv8改进损失函数采用SlideLoss来处理样本不平衡问题,助力涨点

摘要 作者提出了一种基于 YOLOv5 改进的实时人脸检测模型,称为YOLO-FaceV2。设计了一个感受野增强模块(RFE)来提升小尺度人脸的感受野,并引入了 NWD 损失,以弥补 IoU 在小目标位置偏差上的敏感性。针对人脸遮挡问题,提出了 SEAM 注意力模块,并引入了排斥损失进行优化。…

【django】django RESTFramework前后端分离框架快速入门

目录 一、搭建项目开发环境 1.1 pycharm创建项目 1.2 修改配置settings.py 1.3 新增 static与staticfiles文件夹 1.4 生成数据表 1.5 创建超级用户 1.6 启动项目 二、安装REST_Framework 2.1 安装 2.2 配置settings 2.3 重新执行生成数据库脚本 三、修改路由 四、s…

【微服务】Java 对接飞书多维表格使用详解

目录 一、前言 二、前置操作 2.1 开通企业飞书账户 2.2 确保账户具备多维表操作权限 2.3 创建一张测试用的多维表 2.4 获取飞书开放平台文档 2.5 获取Java SDK 三、应用App相关操作 3.1 创建应用过程 3.2 应用发布过程 3.3 应用添加操作权限 四、多维表应用授权操作…

二维legendre多项式

Legendre 多项式常用来表征方形波前的畸变。 目录 一维legendre多项式正交性自正交性 二维Legendre多项式正交性证明 可视化二维 Legendre 多项式解释 Legendre拟合方法1MATLAB 实现解释方法21. 定义一维 Legendre 多项式函数2. 生成二维 Legendre 多项式矩阵3. 计算 Legendre…

台式电脑如何改ip地址:全面解析与实操指南

有时候&#xff0c;由于IP地址冲突、网络安全、隐私保护或特定应用需求&#xff0c;我们可能需要更改台式电脑的IP地址。然而&#xff0c;对于不熟悉网络设置的用户来说&#xff0c;这一过程可能显得复杂而陌生。本文将通过全面解析与实操指南&#xff0c;帮助大家轻松掌握台式…

【私聊记录】最近在忙什么啊?听说你在学人工智能?

小舒&#xff1a;哎&#xff0c;你最近在忙什么啊&#xff1f; 小元&#xff1a;我在学习人工智能呢。 小舒&#xff1a;人工智能&#xff1f;难不难学啊&#xff1f; 小元&#xff1a;不难&#xff0c;找到正确的学习姿势就不难了&#xff01; 小舒&#xff1a;那你为什么想学…

电动越野车行业全面深入分析

电动越野摩托车是将电动技术与越野性能相结合的一类摩托车&#xff0c;采用电力驱动&#xff0c;具有环保、节能、低噪音等优点&#xff0c;同时保留了越野摩托车的强劲动力和适应复杂地形的能力。电动越野摩托车通常配备高性能电动机和电池组&#xff0c;可提供强劲的动力输出…

ctfshow--xss靶场web327-web333(一命速通不了的靶场)

前言 欢迎来到我的博客 个人主页:北岭敲键盘的荒漠猫-CSDN博客 web327 打开页面是一个写信页面。 这里题目暗示不明显。 这里是要给admin写信&#xff0c;让他触发我们的xss。(不看解析不知道有个admin用户) payload: <svg οnlοadwindow.location.hrefhttp://xss平台地址…

法律文件智能识别:免费OCR平台优化数字化管理

一、系统概述 在法律行业&#xff0c;纸质文件的数字化需求日益迫切&#xff0c;合同、判决书、协议等文件的管理成为法律部门的一大难题。传统手动输入不仅耗时&#xff0c;且易出错。思通数科的OCR识别平台应运而生&#xff0c;以其开源、免费的特性为法律文档管理提供了智能…

Flutter-Engine 的定制实践:Text 绘制流程浅析及自定义underline的间距

前言 最近工作中处理的文本相关的内容较多&#xff0c;不论是刁钻的需求还是复杂的问题&#xff0c;最终都会引向一点“Flutter中的文本是如何绘制的&#xff1f;”。 这里我将以“调整下划线与文字的间距”为切入点并结合自定义Engine&#xff0c;记录一下我的个人分析和实践…

“基金申请精要:国自然基金撰写与SCI发表“

国自然基金项目撰写技巧与ChatGPT融合应用 随着社会经济发展和科技进步&#xff0c;基金项目对创新性的要求越来越高。国家级和省级等各类项目的申请层出不穷&#xff0c;项目书的撰写几乎占据了申请人的全年时间。申请人既需要提出独特且有前瞻性的研究问题&#xff0c;具备突…

java的依赖注入

java的依赖注入是个什么东西&#xff1f; 计算机专业相关知识2024-08-07 17:26河北 摘要 •帮你速读文章内容 java中的依赖注入&#xff08;Dependency Injection, DI&#xff09;是一种软件设计模式&#xff0c;用于减少代码间的耦合度。它允许一个对象&#xff08;被依赖的…

别再为质量问题头疼了,六西格玛黑带培训来救场!

六西格玛&#xff0c;这一源自摩托罗拉的先进质量管理理念&#xff0c;以其严谨的数据分析、持续的流程改进和追求卓越的核心价值&#xff0c;在全球范围内赢得了广泛的认可与应用。而六西格玛黑带&#xff0c;作为这一体系中的精英&#xff0c;不仅掌握了深厚的统计学知识&…