第438场周赛:判断操作后字符串中的数字是否相等、提取至多 K 个元素的最大总和、判断操作后字符串中的数字是否相等 Ⅱ、正方形上的点之间的最大距离
Q1、判断操作后字符串中的数字是否相等
1、题目描述
给你一个由数字组成的字符串 s 。重复执行以下操作,直到字符串恰好包含 两个 数字:
- 从第一个数字开始,对于
s中的每一对连续数字,计算这两个数字的和 模 10。 - 用计算得到的新数字依次替换
s的每一个字符,并保持原本的顺序。
如果 s 最后剩下的两个数字 相同 ,返回 true 。否则,返回 false。
2、解题思路
-
计算操作: 对于字符串中的每一对连续数字,计算它们的和 模 10。这个操作会将字符串长度从
n缩短为n-1,直到字符串长度减少到 2。 -
终止条件: 每次操作之后,字符串的长度减少 1。当字符串长度达到 2 时,我们检查这两个数字是否相同。如果相同,返回
true,否则返回false。 -
循环处理: 我们可以使用一个循环来反复进行这些操作,直到字符串长度为 2。每次操作都将原来的字符串转换成新的字符串。
-
代码实现: 采用一个循环来不断执行操作,直到字符串的长度变成 2。每次操作我们计算出新的字符串并继续进行下去,直到符合终止条件。
3、代码实现
class Solution {
public:bool hasSameDigits(string s) {// 当字符串的长度大于 2 时, 继续操作while (s.size() > 2) {string newS; // 用于存储新生成的字符串// 遍历字符串中的每一对连续数字for (int i = 0; i < s.size() - 1; ++i) {// 计算当前数字和下一个数字的和, 并对 10 取模newS.push_back(((s[i] - '0') + (s[i + 1] - '0')) % 10 + '0');}// 用新字符串替换原字符串s = newS;}// 判断最后剩下的两个数字是否相同return s.size() == 2 && s[0] == s[1];}
};

4、复杂度分析
-
时间复杂度:
每次操作将字符串的长度减少 1,直到长度为 2。假设字符串的初始长度是n,那么我们最多进行n - 2次操作。每次操作需要遍历字符串的每一对连续数字,所以每次操作的时间复杂度为O(n)。因此,总的时间复杂度为O(n^2)。 -
空间复杂度:
每次操作都需要使用一个新的字符串newS来保存结果,因此空间复杂度为O(n)。
Q2、提取至多 K 个元素的最大总和
1、题目描述
给你一个大小为 n x m 的二维矩阵 grid ,以及一个长度为 n 的整数数组 limits ,和一个整数 k 。你的目标是从矩阵 grid 中提取出 至多 k 个元素,并计算这些元素的最大总和,提取时需满足以下限制**:**
- 从
grid的第i行提取的元素数量不超过limits[i]。
返回最大总和。
2、解题思路
-
元素选择: 每一行的元素都有一个提取数量的限制,
limits[i]表示从第i行最多可以选择的元素个数。所以,我们需要从每一行中选择最有价值的元素,即每一行的前limits[i]个最大元素。 -
构建候选数组: 我们可以从每一行中选择前
limits[i]个最大元素,这样就得到一个候选元素数组candidates。 -
最大化总和: 在获取了所有候选元素之后,我们将它们排序,并从中选择前
k个最大元素,计算这些元素的总和。 -
步骤:
-
对每一行,按降序排序,选取前
limits[i]个元素。 -
将这些元素放入候选数组
candidates中。 -
对候选数组排序,选取其中前
k个元素,计算这些元素的总和。
-
3、代码实现
class Solution {
public:long long maxSum(vector<vector<int>>& grid, vector<int>& limits, int k) {vector<int> candidates; // 存储所有候选元素// 按行处理for (int i = 0; i < grid.size(); ++i) {// 将当前行的元素按从大到小排序sort(grid[i].rbegin(), grid[i].rend());// 从该行中选择前 limits[i] 个最大的元素for (int j = 0; j < limits[i] && j < grid[i].size(); ++j) {candidates.push_back(grid[i][j]);}}// 将所有候选元素按从大到小排序sort(candidates.rbegin(), candidates.rend());long long sum = 0; // 记录最大总和// 选择前 k 个最大的元素for (int i = 0; i < k && i < candidates.size(); ++i) {sum += candidates[i];}return sum; // 返回最大总和}
};

4、复杂度分析
-
时间复杂度:
-
对于每一行,我们需要对
m个元素进行排序,因此每一行的时间复杂度是O(m log m)。 -
在最坏情况下,我们需要对
n行进行排序,总的时间复杂度是O(n * m log m)。 -
排序候选数组
candidates的时间复杂度是O((n * m) log (n * m))。 -
总的时间复杂度是
O(n * m log m + (n * m) log (n * m))。
-
-
空间复杂度:
-
存储候选元素的数组
candidates的大小为O(n * m)。 -
因此,空间复杂度是
O(n * m)。
-
Q3、判断操作后字符串中的数字是否相等 Ⅱ
1、题目描述
给你一个由数字组成的字符串 s 。重复执行以下操作,直到字符串恰好包含 两个 数字:
- 从第一个数字开始,对于
s中的每一对连续数字,计算这两个数字的和 模 10。 - 用计算得到的新数字依次替换
s的每一个字符,并保持原本的顺序。
如果 s 最后剩下的两个数字相同,则返回 true 。否则,返回 false。
2、解题思路
-
直观理解
-
每一步的操作涉及将字符串中的每对连续数字的和模 10,然后替换原有的数字。这种操作显然会让字符串逐步变短,每次都减少一个字符,直到字符串最终只剩下两个数字。
-
需要判断的是最终剩下的两个数字是否相同。
-
-
深入分析
这个问题的关键在于如何高效地进行操作,特别是在处理大规模字符串时,逐步计算每对连续数字的和模 10 可能会导致时间复杂度过高。为此,我们可以通过一种数学方法来解决这个问题。
-
组合数学: 每次操作其实可以看作是计算当前字符串中的每对数字的影响。为了避免重复计算,我们可以通过数学公式来快速计算每一步的总和,从而推导出最终的结果。
-
欧拉定理与预处理: 为了加速计算,我们可以利用组合数和一些数学优化技巧来快速计算。
-
-
预处理
我们通过以下步骤来预处理数据:
-
阶乘与逆阶乘:为计算组合数快速求解阶乘和逆阶乘。
-
2 和 5 的幂次:由于计算过程中会涉及到取模操作,预处理2和5的幂次有助于我们在计算时直接得到需要的结果。
-
通过这些预处理操作,我们可以在计算过程中避免重复运算,从而提高效率。
3、代码实现
constexpr int MOD = 10; // 模数
constexpr int MX = 100'000; // 最大范围
array<int, MX + 1> f, inv_f, p2, p5; // 预处理的数组// 快速幂函数, 计算 x 的 n 次方模 MOD
int qpow(int x, int n) {int res = 1;while (n > 0) {if (n % 2 > 0) {res = res * x % MOD;}x = x * x % MOD;n /= 2;}return res;
}// 预处理函数, 计算阶乘、逆阶乘、2 的幂次和 5 的幂次
void preprocess() {f[0] = 1;for (int i = 1; i <= MX; i++) {int x = i;// 计算 2 的幂次int e2 = countr_zero((unsigned)x);x >>= e2;// 计算 5 的幂次int e5 = 0;while (x % 5 == 0) {e5++;x /= 5;}f[i] = f[i - 1] * x % MOD;p2[i] = p2[i - 1] + e2;p5[i] = p5[i - 1] + e5;}// 欧拉定理求逆元inv_f[MX] = qpow(f[MX], 3);for (int i = MX; i > 0; i--) {int x = i;x >>= countr_zero((unsigned)x);while (x % 5 == 0) {x /= 5;}inv_f[i - 1] = inv_f[i] * x % MOD;}
}// 组合数计算函数
int comb(int n, int k) {// 由于每项都 < 10,所以无需中途取模return f[n] * inv_f[k] * inv_f[n - k] * qpow(2, p2[n] - p2[k] - p2[n - k]) * qpow(5, p5[n] - p5[k] - p5[n - k]) % MOD;
}class Solution {
public:bool hasSameDigits(string s) {static int initialized = (preprocess(), 0); // 确保预处理只执行一次int diff = 0;// 计算最终两个数字的差值for (int i = 0; i + 1 < s.size(); i++) {diff += comb(s.size() - 2, i) * (s[i] - s[i + 1]);}// 如果差值为 0, 则最终两个数字相同return diff % MOD == 0;}
};

4、复杂度分析
-
时间复杂度:
-
预处理部分的时间复杂度是
O(MX),因为我们需要计算阶乘、逆阶乘以及 2 和 5 的幂次。 -
主逻辑部分遍历字符串
s中的每一对连续数字,进行组合数计算,因此时间复杂度为O(n),其中n是字符串的长度。
-
-
空间复杂度:
- 我们使用了大小为
MX + 1的数组存储阶乘、逆阶乘和幂次,因此空间复杂度为O(MX)。
- 我们使用了大小为
Q4、正方形上的点之间的最大距离
1、题目描述
给你一个整数 side,表示一个正方形的边长,正方形的四个角分别位于笛卡尔平面的 (0, 0) ,(0, side) ,(side, 0) 和 (side, side) 处。
同时给你一个 正整数 k 和一个二维整数数组 points,其中 points[i] = [xi, yi] 表示一个点在正方形边界上的坐标。
你需要从 points 中选择 k 个元素,使得任意两个点之间的 最小 曼哈顿距离 最大化 。
返回选定的 k 个点之间的 最小 曼哈顿距离的 最大 可能值。
两个点 (xi, yi) 和 (xj, yj) 之间的曼哈顿距离为 |xi - xj| + |yi - yj|。
2、解题思路
-
问题转化:
-
在正方形的边界上,曼哈顿距离是一个较为常见的计算问题。
-
给定点在边界上,可以通过对点的位置进行 映射,将其转化为一维空间的问题。
-
通过对这些一维映射后的点进行排序,问题转化为:在一维上选择
k个点,使得它们之间的最小距离最大化。
-
-
一维化点的坐标:
-
我们将正方形的每个边界映射到一维坐标,按照一定的规则进行编码,确保每个点可以用一个唯一的数字来表示。
-
对于正方形的每一边,点的位置可以根据其边的特性进行映射:
- 左边界(
x = 0):坐标y映射为y。 - 上边界(
y = side):坐标x映射为side + x。 - 右边界(
x = side):坐标y映射为side * 3 - y。 - 下边界(
y = 0):坐标x映射为side * 4 - x。
- 左边界(
-
-
排序:
- 通过对所有点进行一维化并排序,问题变得更容易处理。
-
二分搜索与倍增优化:
-
我们使用二分搜索来确定最小距离的最大值。
-
对于每个候选的最小距离,使用倍增技术(类似于跳表的思想)来判断是否能够从已排序的点集中选择出
k个点,保证任意两点之间的距离至少为该最小距离。
-
3、代码实现
class Solution {
public:int maxDistance(int side, vector<vector<int>>& points, int k) {// 将边界上的点映射到一维空间auto mapPoint = [side](int x, int y) -> long long {// 左边界if (x == 0) {return y;}// 上边界if (y == side) {return side + x;}// 右边界if (x == side) {return side * 3LL - y;}// 下边界return side * 4LL - x;};vector<long long> a;for (auto& p : points) {a.push_back(mapPoint(p[0], p[1]));}ranges::sort(a); // 将映射后的点排序int n = a.size();k--; // 往后跳 k-1 步, 这里先减一, 方便计算int high_bit = bit_width((unsigned)k) - 1; // 计算 k 的最高有效位vector<array<int, 5>> nxt(n + 1); // 倍增数组, 5 可以改为 high_bit+1ranges::fill(nxt[n], n); // 哨兵, 表示越界// 检查函数, 判断是否可以在边界上放置 k 个点, 且最小距离不小于 lowauto check = [&](int low) -> bool {// 预处理倍增数组 nxtint j = n;// 转移来源在右边, 要倒序计算for (int i = n - 1; i >= 0; i--) {while (j && a[j - 1] >= a[i] + low) {j--;}nxt[i][0] = j;for (int k = 1; k <= high_bit; k++) {nxt[i][k] = nxt[nxt[i][k - 1]][k - 1];}}// 枚举起点for (int i = 0; i < n; i++) {int cur = i;// 往后跳 k-1 步 (注意上面把 k 减一了)for (int j = high_bit; j >= 0; j--) {if (k >> j & 1) {cur = nxt[cur][j];}}// 出界if (cur == n) {break;}if (a[cur] - a[i] <= side * 4LL - low) {return true;}}return false;};// 二分搜索最大最小距离int left = 1, right = side + 1;while (left + 1 < right) {int mid = left + (right - left) / 2;(check(mid) ? left : right) = mid;}return left;}
};

4、复杂度分析
时间复杂度:
- 排序:对
n个点进行排序的时间复杂度是O(n log n)。 - 二分搜索:在二分搜索过程中,每次检查需要
O(n)的时间,最多进行log(side)次二分查找。因此,总的时间复杂度为O(n log n + n log side)。
空间复杂度:
- 需要额外的
O(n)空间来存储映射后的点以及倍增数组。
相关文章:
第438场周赛:判断操作后字符串中的数字是否相等、提取至多 K 个元素的最大总和、判断操作后字符串中的数字是否相等 Ⅱ、正方形上的点之间的最大距离
Q1、判断操作后字符串中的数字是否相等 1、题目描述 给你一个由数字组成的字符串 s 。重复执行以下操作,直到字符串恰好包含 两个 数字: 从第一个数字开始,对于 s 中的每一对连续数字,计算这两个数字的和 模 10。用计算得到的新…...
20-R 绘图 - 饼图
R 绘图 - 饼图 R 语言提供来大量的库来实现绘图功能。 饼图,或称饼状图,是一个划分为几个扇形的圆形统计图表,用于描述量、频率或百分比之间的相对关系。 R 语言使用 pie() 函数来实现饼图,语法格式如下: pie(x, l…...
【LLM】R1复现项目(SimpleRL、OpenR1、LogitRL、TinyZero)持续更新
note (1)未来的工作需亟待解决: 支持大规模 RL 训练(PPO、GRPO 等)的开源基础框架用于稳定训练的 GRPO 训练超参的自动化调优RL 训练数据的配比(难度、领域、任务等)基于 Instruct 模型训练 R…...
Linux 内核网络设备驱动编程:私有协议支持
一、struct net_device的通用性与私有协议的使用 struct net_device是Linux内核中用于描述网络设备的核心数据结构,它不仅限于TCP/IP协议,还可以用于支持各种类型的网络协议,包括私有协议。其原因如下: 协议无关性:struct net_device的设计是通用的,它本身并不依赖于任何…...
20241130 RocketMQ本机安装与SpringBoot整合
目录 一、RocketMQ简介 ???1.1、核心概念 ???1.2、应用场景 ???1.3、架构设计 2、RocketMQ Server安装 3、RocketMQ可视化控制台安装与使用 4、SpringBoot整合RocketMQ实现消息发送和接收? ? ? ? ? 4.1、添加maven依赖 ???4.2、yaml配置 ???4.3、…...
FFmpeg进化论:从av_register_all手动注册到编译期自动加载的技术跃迁
介绍 音视频开发都知道 FFmpeg,因此对 av_register_all 这个 API 都很熟悉,但ffmpeg 4.0 版本开始就已经废弃了,是旧版本中用于全局初始化的重要接口。 基本功能 核心作用:av_register_all() 用于注册所有封装器(muxer)、解封装器(demuxer)和协议处理器(protocol),…...
Http升级为Https - 开发/测试服环境
1.应用场景 主要用于开发/测试服环境将http升级为https, 防止前端web(浏览器)出现Mixed Content报错; 2.学习/操作 1.文档阅读 deepseek 问答; 2.整理输出 报错信息: Mixed Content: The page at <URL> was loaded over HTTPS, but requested an insecure XMLHttpRequ…...
C语言预编译
大家好,这里是小编的博客频道 小编的博客:就爱学编程 很高兴在CSDN这个大家庭与大家相识,希望能在这里与大家共同进步,共同收获更好的自己!!! 本文目录 引言正文一、预处理的作用与流程…...
算法刷题-字符串-151.反转单词
题目 给一串字符串,里面有若干单词,以空格界定单词的结束,翻转其中的单词 输入:s " hello world " 输出:“world hello” 需要注意的是,给定的字符串可能存在头空格、尾空格以及中间的空格数量…...
单片机裸机编程:状态机与其他高效编程框架
在单片机裸机编程中,状态机是一种非常强大的工具,能够有效管理复杂的逻辑和任务切换。除了状态机,还有其他几种编程模式可以在不使用 RTOS 的情况下实现高效的程序设计。以下是一些常见的方法: 1. 状态机编程 状态机通过定义系统…...
图表控件Aspose.Diagram入门教程:使用 Python 将 VSDX 转换为 PDF
将VSDX转换为PDF可让用户轻松共享图表。PDF 文件保留原始文档的布局和设计。它们广泛用于演示文稿、报告和文档。在这篇博文中,我们将探讨如何在 Python 中将 VSDX 转换为 PDF。 本文涵盖以下主题: Python VSDX 到 PDF 转换器库使用 Python 将 VSDX 转…...
DPVS-1:编译安装DPVS (ubuntu22.04)
操作系统 rootubuntu22:~# lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04.3 LTS Release: 22.04 Codename: jammy rootubuntu22:~# 前置软件准备 apt install git apt install meson apt install gcc ap…...
即将发布书籍 - Yocto项目实战教程:高效定制嵌入式Linux系统
以下这本书《Yocto项目实战教程:高效定制嵌入式Linux系统》即将发布,现在请哪位大佬出山写一个序或者推荐,有兴趣的大佬,请联系我! Git仓库地址: https://github.com/jerrysundev/Yocto-Project-Book.git …...
Git 常用指令及其说明
配置相关 # 配置全局用户名 git config --global user.name "YourUsername"# 配置全局邮箱 git config --global user.email "your.emailexample.com"说明:这两条命令用于设置 Git 全局的用户名和邮箱,在提交代码时,这些…...
nginx代理后502
直接访问 https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions正常 使用nginx代理后访问出现502 server {listen 9999;server_name 172.21.3.78;location ^~ /compatible-mode {proxy_pass https://dashscope.aliyuncs.com;}location / {proxy_pass…...
大模型WebUI:Gradio全解12——LangChain原理及其agent构建Gradio(1)
大模型WebUI:Gradio全解12——LangChain原理及其agent构建Gradio(1) 前言本篇摘要12. LangChain原理及其agent构建Gradio12.1 LangChain概念及优势分析12.1.1 概念12.1.2 标准化组件接口1. 示例:聊天模型2. 示例:检索器12.1.3 编排组件12.1.4 便于部署12.1.5 可观测性和评…...
【Unity】鱼群效果模拟
鱼群效果模拟 文章目录 鱼群效果模拟Boid算法实现方式version1_CPUversion2_GPUversion3_Multilaterationversion4_Bitonic_Sorting (GPU友好)version5_Skinning (TODO) 细节项优化项参考链接 Boid算法 Boid算法是一种模拟群体行…...
PHP入门基础学习五(函数1)
函数 一、概念 1、什么是函数? 函数:封装一段用于完成特定功能的代码 当使用一个函数时,只需关心函数的参数和返回值,就可以完成一个特定的功能 2、php中的函数 PHP 的真正威力源自于它的函数,PHP 中提供了超过 1000 个内建的函数。 php函数分为: 系统内部函数和自…...
微信小程序 - 页面跳转(wx.navigateTo、wx.redirectTo、wx.switchTab、wx.reLaunch)
API 跳转 1、wx.navigateTo (1)基本介绍 功能:保留当前页面,跳转到应用内的某个页面,使用该方法跳转后可以通过返回按钮返回到原页面 使用场景:适用于需要保留当前页面状态,后续还需返回的情…...
Typora的Github主题美化
[!note] Typora的Github主题进行一些自己喜欢的修改,主要包括:字体、代码块、表格样式 美化前: 美化后: 一、字体更换 之前便看上了「中文网字计划」的「朱雀仿宋」字体,于是一直想更换字体,奈何自己拖延症…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
