当前位置: 首页 > news >正文

LeetCode第 458 场周赛题解

题目地址

https://leetcode.cn/contest/weekly-contest-458/

锐评

参赛人数仍然不足2k!留下的应该是纯热爱了吧!

题目难度适中。这Q2确定不是来捣乱的?跟上周Q3几乎一模一样了吧!代码复制过来,改下check里面的符号就可以了。Q4比Q3简单些,先做的Q4。后面发现Q3长度不会溢出,正难则反,跟上周Q4一样,倒着做更简单。

题解

Q1. 用特殊操作处理字符串 I

题意

给你一个字符串 s,它由小写英文字母和特殊字符:*、# 和 % 组成。

请根据以下规则从左到右处理 s 中的字符,构造一个新的字符串 result:

  • 如果字符是 小写 英文字母,则将其添加到 result 中。
  • 字符 ‘*’ 会 删除 result 中的最后一个字符(如果存在)。
  • 字符 ‘#’ 会 复制 当前的 result 并 追加 到其自身后面。
  • 字符 ‘%’ 会 反转 当前的 result。

在处理完 s 中的所有字符后,返回最终的字符串 result。

示例
示例1
输入: s = "a#b%*"
输出: "ba"
说明
is[i]操作当前 result
0‘a’添加 ‘a’“a”
1‘#’复制 result“aa”
2‘b’添加 ‘b’“aab”
3‘%’反转 result“baa”
4‘*’删除最后一个字符“ba”

因此,最终的 result 是 “ba”。

示例2
输入: s = "z*#"
输出: ""
说明
is[i]操作当前 result
0‘z’添加 ‘z’“z”
1‘*’删除最后一个字符“”
2‘#’复制字符串“”

因此,最终的 result 是 “”。

提示
  • 1<=s.length<=201 <= s.length <= 201<=s.length<=20
  • s 只包含小写英文字母和特殊字符 *、# 和 %。
解题思路:模拟

中等题。考虑到字符串长度非常短,直接模拟即可,时间复杂度为O(2n)O(2^n)O(2n)

参考代码(C++)
class Solution {
public:string processStr(string s) {string ans;for (char& ch : s) {if (islower(ch))ans.push_back(ch);else if (ch == '*') {if (!ans.empty())ans.pop_back();} else if (ch == '#')ans += ans;elsereverse(ans.begin(), ans.end());}return ans;}
};

Q2. 最小化连通分量的最大成本

题意

给你一个无向连通图,包含 n 个节点,节点编号从 0 到 n - 1,以及一个二维整数数组 edges,其中 edges[i]=[ui,vi,wi]edges[i] = [u_i, v_i, w_i]edges[i]=[ui,vi,wi] 表示一条连接节点 uiu_iui 和节点 viv_ivi 的无向边,边权为 wiw_iwi,另有一个整数 k。

你可以从图中移除任意数量的边,使得最终的图中 最多 只包含 k 个连通分量。

连通分量的 成本 定义为该分量中边权的 最大值 。如果一个连通分量没有边,则其代价为 0。

请返回在移除这些边之后,在所有连通分量之中的 最大成本 的 最小可能值 。

示例
示例1
输入: n = 5, edges = [[0,1,4],[1,2,3],[1,3,2],[3,4,6]], k = 2
输出: 4
说明

  • 移除节点 3 和节点 4 之间的边(权值为 6)。
  • 最终的连通分量成本分别为 0 和 4,因此最大代价为 4。
示例2
输入: n = 4, edges = [[0,1,5],[1,2,5],[2,3,5]], k = 1
输出: 5
说明

  • 无法移除任何边,因为只允许一个连通分量(k = 1),图必须保持完全连通。
  • 该连通分量的成本等于其最大边权,即 5。
提示
  • 1<=n<=5∗1041 <= n <= 5 * 10^41<=n<=5104
  • 0<=edges.length<=1050 <= edges.length <= 10^50<=edges.length<=105
  • edges[i].length==3edges[i].length == 3edges[i].length==3
  • 0<=ui,vi<n0 <= u_i, v_i < n0<=ui,vi<n
  • 1<=wi<=1061 <= w_i <= 10^61<=wi<=106
  • 1<=k<=n1 <= k <= n1<=k<=n
  • 输入图是连通图。
解题思路:二分+并查集

中等题。看到最大值最小,优先考虑二分。随着最大值约束,越小删除的边也会尽量多,那么连通分量个数也会越多,而题目要求连通分量个数最多只能 k 个,因此符合单调性。时间复杂度为O(nlog(maxW))O(nlog(maxW))O(nlog(maxW)),其中 maxWmaxWmaxW 为边权最大值。

参考代码(C++)
const int maxn = 50'005;
struct dsu {int p[maxn], siz[maxn];int n, cnt;void init(int n) {this->n = this->cnt = n;for (int i = 0; i < n; ++i)p[i] = i, siz[i] = 1;}int findp(int x) {return p[x] == x ? x : p[x] = findp(p[x]);}bool unionp(int x, int y) {int fx = findp(x);int fy = findp(y);if (fx == fy)return false;--cnt;if (siz[fx] >= siz[fy]) {p[fy] = fx;siz[fx] += siz[fy];} else {p[fx] = fy;siz[fy] += siz[fx];}return true;}bool same(int x, int y) {return findp(x) == findp(y);}int sizep(int x) {return siz[findp(x)];}int count() {return cnt;}
} d;class Solution {
public:int minCost(int n, vector<vector<int>>& edges, int k) {auto check = [&](int lim) -> bool {d.init(n);for (auto& e : edges)if (e[2] <= lim)d.unionp(e[0], e[1]);return d.count() <= k;};int l = 0, r = 0, ans = -1;for (auto& e : edges)r = max(r, e[2]);while (l <= r) {int mid = (l + r) >> 1;if (check(mid)) {ans = mid;r = mid - 1;} elsel = mid + 1;}return ans;}
};

Q3. 用特殊操作处理字符串 II

题意

给你一个字符串 s,由小写英文字母和特殊字符:*、# 和 % 组成。

同时给你一个整数 k。

请根据以下规则从左到右处理 s 中每个字符,构造一个新的字符串 result:

  • 如果字符是 小写 英文字母,则将其添加到 result 中。
  • 字符 ‘*’ 会 删除 result 中的最后一个字符(如果存在)。
  • 字符 ‘#’ 会 复制 当前的 result 并 追加 到其自身后面。
  • 字符 ‘%’ 会 反转 当前的 result。

返回最终字符串 result 中第 k 个字符(下标从 0 开始)。如果 k 超出 result 的下标索引范围,则返回 ‘.’。

示例
示例1
输入: s = "a#b%*", k = 1
输出: "a"
说明
is[i]操作当前 result
0‘a’添加 ‘a’“a”
1‘#’复制 result“aa”
2‘b’添加 ‘b’“aab”
3‘%’反转 result“baa”
4‘*’删除最后一个字符“ba”

最终的 result 是 “ba”。下标为 k = 1 的字符是 ‘a’。

示例2
输入: s = "cd%#*#", k = 3
输出: "d"
说明
is[i]操作当前 result
0‘c’添加 ‘c’“c”
1‘d’添加 ‘d’“cd”
2‘%’反转 result“dc”
3‘#’复制 result“dcdc”
4‘*’删除最后一个字符“dcd”
5‘#’复制 result“dcddcd”

最终的 result 是 “dcddcd”。下标为 k = 3 的字符是 ‘d’。

示例3
输入: s = "z*#", k = 0
输出: "."
说明
is[i]操作当前 result
0‘z’添加 ‘z’“z”
1‘*’删除最后一个字符“”
2‘#’复制字符串“”

最终的 result 是 “”。由于下标 k = 0 越界,输出为 ‘.’。

提示
  • 1<=s.length<=1051 <= s.length <= 10^51<=s.length<=105
  • s 只包含小写英文字母和特殊字符 ‘*’、‘#’ 和 ‘%’。
  • 0<=k<=10150 <= k <= 10^{15}0<=k<=1015
  • 处理 s 后得到的 result 的长度不超过 101510^{15}1015
解题思路:思维

难题。看起来好难,因为长度太长了,结果可能太大了,不好处理啊。但是我们注意到提示的最后一条:处理 s 后得到的 result 的长度不超过 101510^{15}1015。这就说明我们可以模拟算出最终长度为多少,设为 cnt,那么如果 k≥cntk \geq cntkcnt,就说明越界了,直接返回 ‘.’。对于不越界的情况怎么处理呢?我们知道随着字符加入,串会越来越长,既然存不下,是不是可以不存直接得到答案?正难则反,我们倒着枚举一下,发现新大陆,可以得到当前字符串长度,又因为字符是从前往后加入的,那么只要我们枚举到某个位置刚好字符串长度为 k+1k + 1k+1,这个字符就是答案。因此我们只需要正序遍历模拟判断无效,倒序遍历模拟找答案即可,时间复杂度为O(n)O(n)O(n)

参考代码(C++)
class Solution {using ll = long long;
public:char processStr(string s, long long k) {ll cnt = 0;for (char& ch : s) {if (islower(ch))++cnt;else if (ch == '*') {if (cnt > 0)--cnt;} else if (ch == '#')cnt += cnt;}if (k >= cnt)return '.';reverse(s.begin(), s.end());for (char& ch : s) {if (islower(ch)) {if (k == cnt - 1)return ch;--cnt;} else if (ch == '*')++cnt;else if (ch == '#') {ll t = cnt >> 1;k %= t;cnt = t;} elsek = cnt - 1 - k;}return '?';}
};

Q4. 图中的最长回文路径

题意

给你一个整数 n 和一个包含 n 个节点的 无向图 ,节点编号从 0 到 n - 1,以及一个二维数组 edges,其中 edges[i]=[ui,vi]edges[i] = [u_i, v_i]edges[i]=[ui,vi] 表示节点 uiu_iui 和节点 viv_ivi 之间有一条边。

同时给你一个长度为 n 的字符串 label,其中 label[i] 是与节点 i 关联的字符。

你可以从任意节点开始,移动到任意相邻节点,每个节点 最多 访问一次。

返回通过访问一条路径,路径中 不包含重复 节点,所能形成的 最长回文串 的长度。

回文串 是指正着读和反着读相同的字符串。

示例
示例1
输入: n = 3, edges = [[0,1],[1,2]], label = "aba"
输出: 3
说明

  • 最长的回文路径是从节点 0 到节点 2,经过节点 1,路径为 0 → 1 → 2,形成字符串 “aba”。
  • 这是一个长度为 3 的回文串。
示例2
输入: n = 3, edges = [[0,1],[0,2]], label = "abc"
输出: 1
说明

  • 没有超过一个节点的路径可以形成回文串。
  • 最好的选择是任意一个单独的节点,构成长度为 1 的回文串。
示例3
输入: n = 4, edges = [[0,2],[0,3],[3,1]], label = "bbac"
输出: 3
说明

  • 最长的回文路径是从节点 0 到节点 1,经过节点 3,路径为 0 → 3 → 1,形成字符串 “bcb”。
  • 这是一个有效的回文串,长度为 3。
提示
  • 1<=n<=141 <= n <= 141<=n<=14
  • n−1<=edges.length<=n∗(n−1)/2n - 1 <= edges.length <= n * (n - 1) / 2n1<=edges.length<=n(n1)/2
  • edges[i]==[ui,vi]edges[i] == [u_i, v_i]edges[i]==[ui,vi]
  • 0<=ui,vi<=n−10 <= u_i, v_i <= n - 10<=ui,vi<=n1
  • ui!=viu_i != v_iui!=vi
  • label.length==nlabel.length == nlabel.length==n
  • label 只包含小写英文字母。
  • 不存在重复边。
解题思路:状压+BFS/DFS

难题。注意到 1<=n<=141 <= n <= 141<=n<=14,很有可能就是暴力,但是此题是 而不是 ,所以重复访问不好处理。考虑状压,点标记是可以了,那么怎么找答案呢?想一想我们之前对于超大回文数是怎么处理的?是不是对半分然后拼接起来?再想想我们之前处理最长回文子串有一种方法是怎么做的?是不是从中心扩展?对于这题,我们同样可以从中心向两边扩展,首先我们只需要将单个点和满足条件的两个点加入,然后开始通过 向两边扩展,同时记录已经访问过的点即可。通过已知两个端点和访问过的点进行标记,最多有 14×14×214=321126414 \times 14 \times 2^{14} = 321126414×14×214=3211264 个状态,可以通过此题。具体可以通过 BFS/DFS 来做扩展操作,时间复杂度为O(n2⋅2n)O(n^2 \cdot 2^n)O(n22n)

参考代码(C++)
class Solution {using tiii = array<int, 3>;
public:int maxLen(int n, vector<vector<int>>& edges, string label) {vector<vector<int>> adj(n);for (auto& e : edges) {adj[e[0]].push_back(e[1]);adj[e[1]].push_back(e[0]);}int m = 1 << n;vector<vector<vector<bool>>> vis(n, vector<vector<bool>>(n, vector<bool>(m, false)));queue<tiii> q;for (int i = 0; i < n; ++i) {int mask = 1 << i;vis[i][i][mask] = true;q.push({i, i, mask});}for (auto& e : edges)if (label[e[0]] == label[e[1]]) {int mask = (1 << e[0]) | (1 << e[1]);if (!vis[e[0]][e[1]][mask]) {vis[e[0]][e[1]][mask] = true;q.push({e[0], e[1], mask});}}int ans = 0;while (!q.empty()) {auto [u, v, mask] = q.front();q.pop();int cnt = __builtin_popcount(mask);ans = max(ans, cnt);for (int& a : adj[u])if (((mask >> a) & 1) == 0)for (int& b : adj[v])if (((mask >> b) & 1) == 0 && a != b && label[a] == label[b]) {int maskt = mask | (1 << a) | (1 << b);if (!vis[a][b][maskt]) {vis[a][b][maskt] = true;q.push({a, b, maskt});}}}return ans;}
};
http://www.dtcms.com/a/277541.html

相关文章:

  • 复习笔记 35
  • PHP语法高级篇(二):文件处理
  • c++ thread_local
  • Java求职面试:从Spring到微服务的全面挑战
  • 牛客周赛 Round 100
  • Android事件分发机制完整总结
  • CMSIS(Cortex Microcontroller Software Interface Standard)ARM公司为 Cortex-M 系列处理器
  • 互联网大厂Java面试:从Spring Boot到微服务的场景应用
  • 2024CVPR:Question Aware Vision Transformer for Multimodal Reasoning介绍
  • 考研复习-数据结构-第六章-图
  • RedisJSON 技术揭秘(五)`JSON.ARRPOP` 原子弹出 修改数组的终极手段
  • git实操
  • HTML 标题标签
  • 香港理工大学实验室定时预约
  • 【windows办公小助手】快速搜索文件及文件所处目录everything
  • 内存对齐与缓存优化:从硬件原理到代码实战
  • 前端进阶之路-从传统前端到VUE-JS(第五期-路由应用)
  • 通信网络编程5.0——JAVA
  • 新手向:使用Python从PDF中高效提取结构化文本
  • LeetCode经典题解:21、合并两个有序链表
  • 【基础算法】倍增
  • Qt:编译qsqlmysql.dll
  • React强大且灵活hooks库——ahooks入门实践之常用场景hook
  • NoSQL 介绍
  • day052-ansible handler、roles与优化
  • Spring AI 项目实战(十七):Spring + AI + 通义千问星辰航空智能机票预订系统(附完整源码)
  • SDN软件定义网络架构深度解析:分层模型与核心机制
  • Datawhale AI 夏令营【更新中】
  • java虚拟线程
  • 面试150 从中序与后序遍历构造二叉树