第431场周赛:最长乘积等价子数组、计算字符串的镜像分数、收集连续 K 个袋子可以获得的最多硬币数量、不重叠区间的最大得分

Q1、最长乘积等价子数组

1、题目描述

给你一个由 正整数 组成的数组 nums

如果一个数组 arr 满足 prod(arr) == lcm(arr) * gcd(arr),则称其为 乘积等价数组 ,其中:

  • prod(arr) 表示 arr 中所有元素的乘积。
  • gcd(arr) 表示 arr 中所有元素的最大公因数 (GCD)。
  • lcm(arr) 表示 arr 中所有元素的最小公倍数 (LCM)。

返回数组 nums最长 乘积等价子数组 的长度。

子数组 是数组中连续的、非空的元素序列。

术语 gcd(a, b) 表示 ab最大公因数

术语 lcm(a, b) 表示 ab最小公倍数

2、解题思路

核心公式的推导
根据公式,我们需要检查:

prod(arr) = lcm(arr) × gcd(arr) \text{prod(arr)} = \text{lcm(arr)} \times \text{gcd(arr)} prod(arr)=lcm(arr)×gcd(arr)

其中:

  • prod(arr) \text{prod(arr)} prod(arr) 是子数组所有元素的乘积;
  • lcm(arr) \text{lcm(arr)} lcm(arr) 是子数组所有元素的最小公倍数,可以通过递归计算得到;
  • gcd(arr) \text{gcd(arr)} gcd(arr) 是子数组所有元素的最大公约数,也可以通过递归计算得到。

暴力枚举子数组
使用双层循环枚举所有可能的子数组的起点和终点,逐步计算子数组的:

  • prod(arr) \text{prod(arr)} prod(arr):通过逐一相乘得到;
  • lcm(arr) \text{lcm(arr)} lcm(arr):动态更新;
  • gcd(arr) \text{gcd(arr)} gcd(arr):动态更新。 对每个子数组,检查是否满足条件。

剪枝优化

  • 如果子数组的乘积 prod(arr) \text{prod(arr)} prod(arr) 超过合理范围(即 maxElement × overallLcm \text{maxElement}×\text{overallLcm} maxElement×overallLcm),直接提前终止当前循环;
  • 用整体数组的最小公倍数 overallLcm \text{overallLcm} overallLcm 来限制子数组可能的最大值,减少不必要的计算。

辅助函数

  • lcm(a, b):计算两个数的最小公倍数。
  • gcd(a, b):计算两个数的最大公约数。

3、代码实现

class Solution {
public:int maxLength(vector<int>& nums) {// 找到数组中的最大值, 用于限制子数组的最大可能 LCM 值int maxElement = *max_element(nums.begin(), nums.end());// 计算整个数组的最小公倍数, 用于减少无效计算int overallLcm = 1;for (int num : nums) {overallLcm = lcm(overallLcm, num);}int maxLength = 0; // 记录满足条件的最长子数组长度// 遍历每个子数组的起点for (int start = 0; start < nums.size(); ++start) {long long product = 1;    // 子数组元素的乘积long long currentLcm = 1; // 子数组的最小公倍数long long currentGcd = 0; // 子数组的最大公约数// 遍历从当前起点开始的子数组for (int end = start; end < nums.size(); ++end) {int currentElement = nums[end];// 更新子数组的乘积、LCM 和 GCDproduct *= currentElement;currentLcm = lcm(currentLcm, currentElement);currentGcd = gcd(currentGcd, currentElement);// 如果乘积等于 LCM * GCD, 则更新最大长度if (product == currentLcm * currentGcd) {maxLength = max(maxLength, end - start + 1);}// 如果当前乘积超过合理范围 (避免无效计算), 提前终止循环if (product > overallLcm * maxElement) {break;}}}return maxLength;}private:// 计算两个数的 LCM(最小公倍数)long long lcm(long long a, long long b) { return (a * b / gcd(a, b));}// 计算两个数的 GCD (最大公约数)long long gcd(long long a, long long b) {return b == 0 ? a : gcd(b, a % b);}
};

在这里插入图片描述

4、复杂度分析

时间复杂度

  • 外层循环:遍历所有可能的子数组起点 O(n);
  • 内层循环:遍历每个起点对应的终点,最坏情况下是 O(n);
  • 动态更新 LCM 和 GCD 的复杂度约为 O ( log ⁡ ( maxElement ) ) O(\log(\text{maxElement})) O(log(maxElement))
    综合复杂度为 O ( n 2 log ⁡ ( maxElement ) ) O(n^2 \log(\text{maxElement})) O(n2log(maxElement))

空间复杂度
使用常量辅助空间,因此空间复杂度为 O(1)。


Q2、计算字符串的镜像分数

1、题目描述

给你一个字符串 s

英文字母中每个字母的 镜像 定义为反转字母表之后对应位置上的字母。例如,'a' 的镜像是 'z''y' 的镜像是 'b'

最初,字符串 s 中的所有字符都 未标记

字符串 s 的初始分数为 0 ,你需要对其执行以下过程:

  • 从左到右遍历字符串。
  • 对于每个下标 i ,找到距离最近的 未标记 下标 j,下标 j 需要满足 j < is[j]s[i] 的镜像。然后 标记 下标 ij,总分加上 i - j 的值。
  • 如果对于下标 i,不存在满足条件的下标 j,则跳过该下标,继续处理下一个下标,不需要进行标记。

返回最终的总分。

2、解题思路

初始化数据结构:

  • 使用一个大小为 26 的向量 charStacks,其中每个元素是一个栈,表示英文字母从 'a''z' 的未标记位置索引。
  • 用变量 totalScore 记录最终分数。

遍历字符串:

  • 遍历字符串的每个字符,计算其索引和镜像索引。
  • 如果当前字符的镜像栈中有元素 (存在未标记的镜像字符索引),从镜像栈中弹出栈顶元素,计算得分并累加到 totalScore
  • 如果镜像栈为空,则将当前字符索引压入该字符的栈中。

返回总分:

  • 遍历完成后,totalScore 即为最终结果。

3、代码实现

class Solution {
public:long long calculateScore(string s) {// 使用26个栈, 分别对应 a-z 的字符vector<stack<int>> charStacks(26);long long totalScore = 0; // 记录总得分// 遍历字符串中的每个字符for (int index = 0; index < s.size(); ++index) {int currentChar = s[index] - 'a';         // 当前字符的索引 (0-25)int complementaryChar = 25 - currentChar; // 互补字符的索引 (0-25)// 如果互补字符的栈不为空, 则可以匹配, 计算得分if (!charStacks[complementaryChar].empty()) {// 计算当前得分: 当前索引减去互补字符的最近索引totalScore += index - charStacks[complementaryChar].top();// 弹出互补字符的栈顶元素 (标记为已使用)charStacks[complementaryChar].pop();} else {// 否则, 将当前字符的索引压入对应栈charStacks[currentChar].push(index);}}return totalScore; // 返回总得分}
};

在这里插入图片描述

4、复杂度分析

时间复杂度
每个字符在遍历过程中只会被压栈和弹栈一次,时间复杂度为 O(n)。

空间复杂度
需要额外的 26 个栈,每个栈的大小总和不超过 n,空间复杂度为 O(n)。


Q3、收集连续 K 个袋子可以获得的最多硬币数量

1、题目描述

在一条数轴上有无限多个袋子,每个坐标对应一个袋子。其中一些袋子里装有硬币。

给你一个二维数组 coins,其中 coins[i] = [li, ri, ci] 表示从坐标 liri 的每个袋子中都有 ci 枚硬币。

数组 coins 中的区间互不重叠。

另给你一个整数 k

返回通过收集连续 k 个袋子可以获得的 最多 硬币数量。

2、解题思路

滑动窗口法

由于地毯覆盖的是连续的袋子,因此我们可以用 滑动窗口 来计算当前地毯位置下的硬币总和,并动态调整窗口以获取最大硬币数。

  • 使用窗口 [left, right] 表示当前地毯覆盖的范围。
  • 窗口右边界扩展:每次将当前区间的硬币加入到总和中。
  • 窗口左边界收缩:当地毯的覆盖范围超过 k 时,移除左边部分的硬币。

双向覆盖

为了考虑不同覆盖方向(从左到右,从右到左)的影响,算法需要:

  1. 按照区间起点升序排序,计算从左到右的最大覆盖硬币数。
  2. 将区间起点和终点取反后再次排序,计算从右到左的最大覆盖硬币数。

最终结果为两种覆盖方向的最大值。

3、代码实现

class Solution {
public:long long maximumCoins(vector<vector<int>>& coins, int carpetLen) {// 按起点升序排序区间, 方便从左到右计算sort(coins.begin(), coins.end());// 计算从左到右的最大硬币覆盖数量long long maxCoins = calculateMaxCoins(coins, carpetLen);// 反转每个区间的起点和终点for (auto& tile : coins) {int temp = tile[0];tile[0] = -tile[1];         // 起点变为负的终点tile[1] = -temp;            // 终点变为负的起点}// 按新起点升序排序区间, 方便从右到左计算sort(coins.begin(), coins.end());// 计算从右到左的最大硬币覆盖数量, 并更新最终结果maxCoins = max(maxCoins, calculateMaxCoins(coins, carpetLen));return maxCoins;}private:// 计算滑动窗口内的最大硬币覆盖数量long long calculateMaxCoins(const vector<vector<int>>& tiles, int carpetLen) {long long maxCovered = 0;       // 记录最大覆盖硬币数long long currentCovered = 0;   // 当前窗口的硬币总数int left = 0;                   // 左指针, 表示窗口的起始位置// 遍历每个区间, 调整滑动窗口for (int right = 0; right < tiles.size(); ++right) {int start = tiles[right][0]; // 当前区间的起始位置int end = tiles[right][1];   // 当前区间的终点位置int coins = tiles[right][2]; // 当前区间的硬币数// 增加当前区间的硬币到窗口总和currentCovered += static_cast<long long>(end - start + 1) * coins;// 如果当前窗口超出地毯长度, 收缩左指针while (tiles[left][1] + carpetLen - 1 < end) {int leftStart = tiles[left][0];int leftEnd = tiles[left][1];int leftCoins = tiles[left][2];// 减去左指针对应的硬币数currentCovered -= static_cast<long long>(leftEnd - leftStart + 1) * leftCoins;++left; // 左指针右移}// 计算当前窗口的未完全覆盖部分, 并更新最大覆盖硬币数long long uncovered = max(static_cast<long long>(end - carpetLen + 1 - tiles[left][0]) * tiles[left][2], 0LL);maxCovered = max(maxCovered, currentCovered - uncovered);}return maxCovered; // 返回当前方向的最大硬币覆盖数}
};

在这里插入图片描述

4、复杂度分析

时间复杂度

  • 排序:两次排序,时间复杂度为 O ( n log ⁡ n ) O(n \log n) O(nlogn),其中 n 是区间数量。
  • 滑动窗口:遍历每个区间的右边界,时间复杂度为 O ( n ) O(n) O(n)
  • 总时间复杂度为 O ( n log ⁡ n ) O(n \log n) O(nlogn)

空间复杂度

  • 使用了辅助变量和少量指针,空间复杂度为 O ( 1 ) O(1) O(1)

Q4、不重叠区间的最大得分

1、题目描述

给你一个二维整数数组 intervals,其中 intervals[i] = [li, ri, weighti]。区间 i 的起点为 li,终点为 ri,权重为 weighti。你最多可以选择 4 个互不重叠 的区间。所选择区间的 得分 定义为这些区间权重的总和。

返回一个至多包含 4 个下标且字典序最小的数组,表示从 intervals 中选中的互不重叠且得分最大的区间。

如果两个区间没有任何重叠点,则称二者 互不重叠 。特别地,如果两个区间共享左边界或右边界,也认为二者重叠。

数组 a 的字典序小于数组 b 的前提是:当在第一个不同的位置上,a 的元素小于 b 的对应元素。如果前 min(a.length, b.length) 个元素均相同,则较短的数组字典序更小。

2、解题思路

  1. 预处理与排序:

    • 将输入数据转换为结构体数组以便操作。

    • 按区间的 右端点升序 排序,方便后续计算前一个不重叠区间。

  2. 动态规划:

    • 定义 dp[i][j] 表示前 i 个区间中选择 j 个的最大权重及对应区间索引。

    • 对于每个区间,既可以选择,也可以不选择;需要比较两种情况:

      • 不选择:直接继承前一个状态。
      • 选择:通过二分找到最后一个不与当前区间重叠的区间,加上当前权重。
      • 若两种选择的权重相等,则选择字典序更小的方案。
  3. 回溯最优解:

    • 最终结果是 dp[n][4],即前 n 个区间中选择最多 4 个的最优解。

3、代码实现

class Solution {
private:struct Interval {int start;  // 区间起点int end;    // 区间终点int weight; // 区间权重int index;  // 区间索引};public:vector<int> maximumWeight(vector<vector<int>>& intervals) {int n = intervals.size();// 1. 将输入的二维数组转换为结构体数组, 便于操作vector<Interval> sortedIntervals(n);for (int i = 0; i < n; ++i) {sortedIntervals[i] = {intervals[i][0], intervals[i][1], intervals[i][2], i};}// 2. 按区间的右端点升序排序sort(sortedIntervals.begin(), sortedIntervals.end(),[](const Interval& a, const Interval& b) {return a.end < b.end;});// 3. 动态规划表, dp[i][j] 表示前 i 个区间选择 j 个的最大权重及对应区间索引vector<array<pair<long long, vector<int>>, 5>> dp(n + 1);for (int i = 0; i < n; ++i) {const auto& current = sortedIntervals[i];// 找到当前区间左端点之前结束的最近区间索引int previous = lower_bound(sortedIntervals.begin(), sortedIntervals.begin() + i, current.start,[](const Interval& interval, int value) {return interval.end < value;}) - sortedIntervals.begin();for (int j = 1; j < 5; ++j) {// 不选当前区间的情况long long excludeWeight = dp[i][j].first;// 选当前区间的情况long long includeWeight = dp[previous][j - 1].first + current.weight;// 如果选择当前区间更优, 则更新 DP 表if (excludeWeight < includeWeight) {vector<int> newIndices = dp[previous][j - 1].second;newIndices.push_back(current.index);sort(newIndices.begin(), newIndices.end()); // 保持字典序// 更新权重和区间索引dp[i + 1][j] = {includeWeight, newIndices};} else if (excludeWeight > includeWeight) {// 如果不选当前区间更优,则继承上一步的状态dp[i + 1][j] = dp[i][j];} else {// 如果两种选择权重相等, 选择字典序更小的方案vector<int> newIndices = dp[previous][j - 1].second;newIndices.push_back(current.index);sort(newIndices.begin(), newIndices.end()); // 保持字典序if (dp[i][j].second < newIndices) {dp[i + 1][j] = dp[i][j];} else {dp[i + 1][j] = {includeWeight, newIndices};}}}}// 4. 返回选择 4 个区间时的区间索引return dp[n][4].second;}
};

在这里插入图片描述

4、时间复杂度分析

  1. 排序: O ( n log ⁡ n ) O(n \log n) O(nlogn)
  2. 动态规划: O ( n × 4 × log ⁡ n ) O(n \times 4 \times \log n) O(n×4×logn),二分查找的复杂度为 O ( log ⁡ n ) O(\log n) O(logn)
  3. 总复杂度: O ( n log ⁡ n ) O(n \log n) O(nlogn)


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

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

相关文章

小程序租赁系统开发的优势与应用前景分析

内容概要 小程序租赁系统是一种新兴的数字化解决方案&#xff0c;旨在为用户提供更加便捷与高效的租赁服务。它通常包括一系列功能&#xff0c;如在线浏览、即时预定、支付功能以及用户反馈机制。这些系统在使用上极为友好&#xff0c;让用户能够轻松选择所需的商品或服务&…

Uniapp Android 本地离线打包(详细流程)

一、简介 App 离线 SDK 暂时不支持 Kotlin&#xff0c;未来不清楚。 uniapp 提供了 云打包 与 本地打包 两种方案&#xff0c;云打包 需要排队且还有次数限制&#xff0c;本地打包 则就没有这些限制&#xff0c;而且会 本地打包 对开发 原生插件 有很大的帮助。 细节&#x…

GPT系统重大升级,开创国内先河:o1支持图片识别功能正式上线

文章目录 零、前言一、授权码登录体验优化&#xff1a;一步直达聊天界面二、全新“项目”功能&#xff1a;让工作更有条理三、语音功能升级&#xff1a;全新交互体验四、o1支持图片识别五、总结 零、前言 我是虚竹哥&#xff0c;目标是带十万人玩转ChatGPT。 亲爱的用户&…

音视频入门基础:MPEG2-PS专题(3)——MPEG2-PS格式简介

一、引言 本文对MPEG2-PS格式进行简介。 进行简介之前&#xff0c;请各位先下载MPEG2-PS的官方文档。ITU-T和ISO/IEC都分别提供MPEG2-PS的官方文档。但是ITU提供的文档是免费的&#xff0c;ISO/IEC是付费的&#xff0c;所以我们主要阅读ITU提供的官方文档&#xff0c;比如较新…

概述(讲讲python基本语法和第三方库)

我是北子&#xff0c;这是我自己写的python教程&#xff0c;主要是记录自己的学习成果方便自己日后复习&#xff0c; 我先学了C/C&#xff0c;所以这套教程中可能会将很多概念和C/C去对比&#xff0c;所以该教程大概不适合零基础的人。 it seems that python nowadays 只在人工…

Java jni调用nnom rnn-denoise 降噪

介绍&#xff1a;https://github.com/majianjia/nnom/blob/master/examples/rnn-denoise/README_CN.md 默认提供了一个wav的例子 #include <stdint.h> #include <stdlib.h> #include <stdio.h> #include <math.h> #include <string.h>#include …

【软考网工笔记】计算机基础理论与安全——网络规划与设计

HFC 混合光纤同轴电缆网 HFC: Hybrid Fiber - Coaxial 的缩写&#xff0c;即混合光纤同轴电缆网。是一种经济实用的综合数字服务宽带网接入技术。 HFC 通常由光纤干线、同轴电缆支线和用户配线网络三部分组成&#xff0c;从有线电视台出来的节目信号先变成光信号在干线上传输…

记录一次电脑被入侵用来挖矿的过程(Trojan、Miner、Hack、turminoob)

文章目录 0、总结1、背景2、端倪3、有个微软的系统更新&#xff0c;就想着更新看看&#xff08;能否冲掉问题&#xff09;4、更新没成功&#xff0c;自动重启电脑5、风险文件&#xff08;好家伙命名还挺规范&#xff0c;一看名字就知道出问题了&#xff09;6、开机有一些注册表…

Qt 5.14.2 学习记录 —— 일 新项目

文章目录 1、创建2、查看代码 ---- main.cpp3、查看代码 ---- widgt.h4、查看代码 ---- widgt.cpp和widget.ui5、查看代码 ---- Empty.pro6、运行产生的中间文件 1、创建 左上角的文件&#xff0c;新建文件或项目。如果要写一个GUI程序&#xff0c;应当选择Application&#x…

vscode如何离线安装插件

在没有网络的时候,如果要安装插件,就会麻烦一些,需要通过离线安装的方式进行。下面记录如何在vscode离线安装插件。 一、下载离线插件 在一台能联网的电脑中,下载好离线插件,拷贝到无法联网的电脑上。等待安装。 vscode插件商店地址:https://marketplace.visualstudio.co…

数据仓库中的指标体系模型介绍

数据仓库中的指标体系介绍 文章目录 数据仓库中的指标体系介绍前言什么是指标体系指标体系设计有哪些模型?1. 指标分层模型2. 维度模型3. 指标树模型4. KPI&#xff08;关键绩效指标&#xff09;模型5. 主题域模型6.平衡计分卡&#xff08;BSC&#xff09;模型7.数据指标框架模…

2025元旦源码免费送

我们常常在当下感到时间慢&#xff0c;觉得未来遥远&#xff0c;但一旦回头看&#xff0c;时间已经悄然流逝。对于未来&#xff0c;尽管如此&#xff0c;也应该保持一种从容的态度&#xff0c;相信未来仍有许多可能性等待着我们。 免费获取源码。 更多内容敬请期待。如有需要可…

2025年Stable Diffusion安装教程(超详细)

StableDiffusion的安装部署其实并不困难&#xff0c;只需简单点击几下&#xff0c;几分钟就能安装好&#xff0c;不管是windows还是苹果mac电脑&#xff0c;关于StableDiffusion的各种安装方式&#xff0c;这片文章一一来给大家讲明白。&#xff08;所有安装资料都给大家整理好…

【openwrt】OpenWrt 路由器的 802.1X 动态 VLAN

参考链接 [OpenWrt Wiki] Wi-Fi /etc/config/wirelesshttps://openwrt.org/docs/guide-user/network/wifi/basic#wpa_enterprise_access_point 介绍 基于802.1X 无线网络身份验证࿰

Android12 App窗口创建流程

有关的窗口对象 PhoneWindowActivityThread#performLaunchActivity {Activity.attach}Surface new ViewRootImpl 创建null对象 mSurface.transferFrom(getOrCreateBLASTSurface())//填充内容 LayerSurfaceFlinger::createLayerSurfaceControlViewRootImpl#relayoutWindow{mSur…

Leetcode打卡:设计一个ATM机器

执行结果&#xff1a;通过 题目 2241 设计一个ATM机器 一个 ATM 机器&#xff0c;存有 5 种面值的钞票&#xff1a;20 &#xff0c;50 &#xff0c;100 &#xff0c;200 和 500 美元。初始时&#xff0c;ATM 机是空的。用户可以用它存或者取任意数目的钱。 取款时&#xff0c…

在CodeBlocks搭建SDL2工程构建TFT彩屏模拟器虚拟TFT彩屏幕显示

在CodeBlocks搭建SDL2工程构建TFT彩屏模拟器虚拟TFT彩屏幕显示 参考文章源码下载地址一、SDL2的创建、初始化、退出二、系统基本Tick、彩屏刷新、按键事件三、彩屏获取与设置颜色四、彩屏填充颜色及清屏五、彩屏显示中文和英文字符串六、彩屏显示数字七、彩屏初始化八、主函数测…

ESP8266+STM32+阿里云保姆级教程(AT指令+MQTT)

前言&#xff1a;在开发过程中&#xff0c;几乎踩便了所有大坑小坑总结出的文章&#xff0c;我是把坑踩满了&#xff0c;帮助更过小白快速上手&#xff0c;如有错误之处&#xff0c;还麻烦各位大佬帮忙指正、 目录 一、ESP-01s介绍 1、ESP-01s管脚功能&#xff1a; 模组启动模…

美的空气净化器好用吗?拾梧、美的、戴森空气净化器除烟哪个好?

说到二手烟&#xff0c;这可真是个让人头疼的问题&#xff01;它里面含有超过7000种化学物质&#xff0c;形式多样&#xff0c;处理起来比甲醛这些传统污染物难多了。在市场上那么多空气净化器里&#xff0c;要挑一个能真正对付二手烟的&#xff0c;简直就像大海捞针一样难。不…

【机器学习】穷理至极,观微知著:微积分的哲思之旅与算法之道

文章目录 微积分基础&#xff1a;理解变化与累积的数学前言一、多重积分的高级应用1.1 高维概率分布的期望值计算1.1.1 多维期望值的定义1.1.2 Python代码实现1.1.3 运行结果1.1.4 结果解读 1.2 特征空间的体积计算1.2.1 单位球体的体积计算1.2.2 Python代码实现1.2.3 运行结果…