Leetcode - 周赛425
目录
一,3364. 最小正和子数组
二, 3365. 重排子字符串以形成目标字符串
三,3366. 最小数组和
四,3367. 移除边之后的权重最大和
一,3364. 最小正和子数组

本题可以直接暴力枚举,代码如下:
class Solution {public int minimumSumSubarray(List<Integer> nums, int l, int r) {int n = nums.size();int ans = Integer.MAX_VALUE;for(int k=l; k<=r; k++){int s = 0;for(int i=0, j=0; j<n; j++){s += nums.get(j);if(j-i+1 > k){s -= nums.get(i);i++;}if(j-i+1 == k && s > 0) ans = Math.min(ans, s);}}return ans==Integer.MAX_VALUE ? -1 : ans;}
}
如果它的数据范围更大一点,上述做法会超时,所以这里再介绍一个O(n*logn)的做法:
- 这题求子数组和的最小正值,子数组和可以直接使用前缀和来求
- 题目要求子数组的长度在 [L,R] 之间,可以枚举左端点 / 右端点,这里选择枚举右端点下标 i,再根据上述条件直接推出左端点的下标 j 的范围 [i-R,i-L]
- 假设前缀和数组为 s,此时 si 是固定的,要使得 si - sj 的值更大,sj 必须是小于 si 的最大值(题目要求为正数),求 sj < si 的最大值且 j 属于 [i-R,i-L],这可以使用有序集合+二分来做
代码如下:
class Solution {public int minimumSumSubarray(List<Integer> nums, int l, int r) {int n = nums.size();int ans = Integer.MAX_VALUE;int[] pre = new int[n+1];for(int i=0; i<n; i++){pre[i+1] = pre[i] + nums.get(i);}//枚举右端点:[i-r, i-l] ~ i//s[i-r, i-l] < si, 二分枚举最接近si的值 TreeMap<Integer, Integer> map = new TreeMap<>();for(int i=l, j=0; i<=n; i++){map.merge(pre[i-l], 1, Integer::sum);// 错误写法:// 当l==r时,会出错(没有计算当前子数组的大小)// if(i-r > 0){// map.merge(pre[i-r], -1, Integer::sum);// if(map.get(pre[i-r])==0) map.remove(pre[i-r]);// } Integer res = map.lowerKey(pre[i]);if(res != null)ans = Math.min(ans, pre[i]-res);if(i-r >= 0){map.merge(pre[i-r], -1, Integer::sum);if(map.get(pre[i-r])==0) map.remove(pre[i-r]);} }return ans == Integer.MAX_VALUE ? -1 : ans;}
}
二, 3365. 重排子字符串以形成目标字符串

本题直接暴力哈希,使用哈希表统计字符串 s 中分割成 k 个等长的子字符串,再看 t 中分割出的 k 个等长子字符串是否与字符串 s 完全相同。
代码如下:
class Solution {public boolean isPossibleToRearrange(String s, String t, int k) {Map<String, Integer> map = new HashMap<>();int n = s.length();for(int i=n/k; i<=n; i+=n/k){map.merge(s.substring(i-n/k, i), 1, Integer::sum);}for(int i=n/k; i<=n; i+=n/k){String x = t.substring(i-n/k, i);map.merge(x, -1, Integer::sum);if(map.get(x) == 0) map.remove(x);if(map.getOrDefault(x, 0) < 0) return false; }return map.size() == 0;}
}
三,3366. 最小数组和

本题数据范围较小,直接使用dp暴力求解,先找与原问题相同的子问题,从前往后遍历,对于第 i 个数来说:
- 不执行任何操作,剩下变成求 [i+1,n] 这些数进行 x 次操作1,y 次操作2后的最小元素和
- 执行操作1,剩下变成求 [i+1,n] 这些数进行 x-1 次操作1,y 次操作2后的最小元素和
- 执行操作2,剩下变成求 [i+1,n] 这些数进行 x 次操作1,y-1 次操作2后的最小元素和
- 执行操作1和操作2,剩下变成求 [i+1,n] 这些数进行 x-1 次操作1,y-1 次操作2后的最小元素和
定义 dfs(i,x,y):对 [i,n] 进行 x 次操作1,y 次操作2后的最小元素和,对于 nums[i] 进行分类讨论:
- 不执行任何操作,剩下变成求 [i+1,n] 这些数进行 x 次操作1,y次操作2后的最小元素和,即dfs(i+1,x,y) + nums[i]
- 执行操作1,剩下变成求 [i+1,n] 这些数进行 x-1 次操作1,y次操作2后的最小元素和,即dfs(i+1,x-1,y) + (nums[i]+1)/2
- 执行操作2,剩下变成求 [i+1,n] 这些数进行 x 次操作1,y-1次操作2后的最小元素和,即dfs(i+1,x,y-1) + nums[i] - k
- 执行操作1和操作2,剩下变成求 [i+1,n] 这些数进行 x-1 次操作1,y-1次操作2后的最小元素和,即 dfs(i+1,x-1,y-1) + (nums[i] - k + 1)/2,同时操作时先2后1更优,(nums[i]+1)/2 - k >= (nums[i]-k+1)/2
代码如下:
class Solution {public int minArraySum(int[] nums, int k, int op1, int op2) {int n = nums.length;memo = new int[n][op1+1][op2+1];for (int[][] mat : memo) {for (int[] row : mat) {Arrays.fill(row, -1); // -1 表示没有计算过}}return dfs(0, op1, op2, k, nums);}int[][][] memo;int dfs(int i, int x, int y, int k, int[] nums){if(i == nums.length) return 0;if(memo[i][x][y] != -1) return memo[i][x][y];int res = dfs(i+1, x, y, k, nums) + nums[i];if(x > 0)res = Math.min(res, dfs(i+1, x-1, y, k, nums) + (nums[i]+1)/2);if(y > 0 && nums[i] >= k){res = Math.min(res, dfs(i+1, x, y-1, k, nums) + nums[i] - k);if(x > 0){int t = (nums[i]+1)/2 >= k ? (nums[i]+1)/2 - k : (nums[i]-k+1)/2;res = Math.min(res, dfs(i+1, x-1, y-1, k, nums) + t);}}return memo[i][x][y] = res;}
}
递推代码:
class Solution {public int minArraySum(int[] nums, int k, int op1, int op2) {int n = nums.length;int[][][] f = new int[n+1][op1+1][op2+1];for(int i=n-1; i>=0; i--){for(int x=0; x<=op1; x++){for(int y=0; y<=op2; y++){f[i][x][y] = f[i+1][x][y] + nums[i];if(x > 0)f[i][x][y] = Math.min(f[i][x][y], f[i+1][x-1][y] + (nums[i]+1)/2);if(y > 0 && nums[i] >= k){f[i][x][y] = Math.min(f[i][x][y], f[i+1][x][y-1] + nums[i] - k);if(x > 0){int t = (nums[i]+1)/2 >= k ? (nums[i]+1)/2 - k : (nums[i]-k+1)/2;f[i][x][y] = Math.min(f[i][x][y], f[i+1][x-1][y-1] + t);}}}}}return f[0][op1][op2];}
}
四,3367. 移除边之后的权重最大和


代码如下:
class Solution {public long maximizeSumOfWeights(int[][] edges, int k) {int n = edges.length;List<int[]>[] g = new ArrayList[n+1];Arrays.setAll(g, e -> new ArrayList<>());for(int[] e : edges){int x = e[0], y = e[1], val = e[2];g[x].add(new int[]{y, val});g[y].add(new int[]{x, val});}long[] f = dfs(0, -1, k, g);return f[1];//{s, s+first} f[1] >= f[0]}long[] dfs(int x, int fa, int k, List<int[]>[] g){PriorityQueue<Long> que = new PriorityQueue<>();//默认最小堆long s = 0;for(int[] y : g[x]){if(y[0] == fa) continue;long[] f = dfs(y[0], x, k, g);//选/不选 x-y 这条边 f[0]+y[1]/f[1]//选/不选 怎么在至多 选K个边 的情况下,使其最大?//先把不选的值全部求和,在求出如果选相较于不选提升了多少,//对其进行排序,选择k个提升最大的if(que.size() == k && que.peek() < f[0] + y[1] - f[1]){que.poll();}if(que.size() < k && f[0] + y[1] - f[1] > 0){que.offer(f[0] + y[1] - f[1]);}s += f[1];}long first = que.size() == k ? que.poll() : 0;while(!que.isEmpty()){s += que.poll();}return new long[]{s, s+first};}
}
相关文章:
Leetcode - 周赛425
目录 一,3364. 最小正和子数组 二, 3365. 重排子字符串以形成目标字符串 三,3366. 最小数组和 四,3367. 移除边之后的权重最大和 一,3364. 最小正和子数组 本题可以直接暴力枚举,代码如下: …...
c++(斗罗大陆2)
我把魂力等级更新到了31级 #include<iostream> #include<conio.h> #include<windows.h> #include<stdlib.h> #include<stdio.h> #include<time.h> #include<string.h> using namespace std; int qs10; int xthl0;//先…...
redis常见数据类型
Redis是一个开源的、内存中的数据结构存储系统,它可以用作数据库、缓存和消息代理,支持多种数据类型。 一、数据类型介绍 String(字符串) Redis中最基本的数据类型。可以存储任何类型的数据,包括字符串、数字和二进制…...
MySQL - 性能优化
使用 Explain 进行分析 Explain 用来分析 SELECT 查询语句,开发人员可以通过分析 Explain 结果来优化查询语句。 比较重要的字段有: select_type : 查询类型,有简单查询、联合查询、子查询等 key : 使用的索引 rows : 扫描的行数 type :…...
Linux进程概念-详细版(一)
目录 进程概念 描述进程-PCB task_struct-PCB的一种 task_struct内容分类 查看进程 通过系统目录查看 通过ps命令查看 通过系统调用获取进程的PID和PPID 通过系统调用创建进程 fork的认识 使用if进行分流 最后的总结 Linux进程状态 运行状态-R 浅度睡眠状态-S 深度睡…...
K8S网络系列--Flannel网络下UDP、VXLAN模式的通信流程机制分析
文章目录 前言一、了解overlay、underlay容器网络二、网络通信1.分类2.网络虚拟设备对2.1、什么是网络虚拟设备对veth pair?2.2、如何查看容器的网卡与主机的哪个veth设备对是成对的关系? 3、vxlan和vtep3.1、vtep3.2、vxlan相关概念 三、Flannel网络模式剖析0、flannel的作用…...
ThreadLocal的设计思考
问题的提出 在Java多线程中,共享变量的读写非常容易出现不可预测的行为,因此对共享变量的访问控制非常重要。因此在多线程编程时,为了保证线程安全,需要进行额外的同步措施。比如典型的操作就是加锁。除了加锁外,另一…...
shell脚本练习(2)
1. 使用case实现成绩优良差的判断 2. for创建20用户 用户前缀由用户输入 用户初始密码由用户输入 例如:test01,test10 3. for ping测试指网段的主机 网段由用户输入,例如用户输入192.168.2 ,则ping 192.168.2.10 --- 192.168.2.2…...
通讯专题4.1——CAN通信之计算机网络与现场总线
从通讯专题4开始,来学习CAN总线的内容。 为了更好的学习CAN,先从计算机网络与现场总线开始了解。 1 计算机网络体系的结构 在我们生活当中,有许多的网络,如交通网(铁路、公路等)、通信网(电信、…...
Harmony NEXT-越过相机读写权限上传图片至项目云存储中
问题成因 在制作用户注册登录界面时想要实现用户头像上传共能,查询API文档,发现有picker和PhotoAccessHelper两个包可以选择使用,但是在使用PhotoAccessHelper包拉起相册并读入所选的照片后将该照片传入云存储中产生报错,需要相册…...
MATLAB基础应用精讲-【数模应用】Retinex图像去雾算法(附MATLAB和python代码实现)
目录 前言 算法原理 图像去雾 数学模型 算法步骤 算法拓展 多尺度Retinex (MSR) 算法 MSR算法的实现细节 McCann Retinex 算法 McCann99 Retinex算法 基于暗通道先验的图像去雾算法 暴力解法——直方图均衡化去雾 基于Retinex理论的图像去雾 基于暗通道先验的单…...
点击A组件跳转到B页面的tab的某一列
1、使用vuex存储点击的数据; 点击A组件里面的button按钮: <div><button click"banli(first)">已办理</button><button click"banli(second)">未办理</button><button click"banli(third)&quo…...
HarmonyOS xml转换JavaScript 常用的几个方法
HarmonyOS 使用 xml转换JavaScript 的好处 易用性: 提供了简洁的API接口,使得XML到JavaScript对象的转换变得简单直接。转换选项的灵活性允许开发者根据实际需求自定义转换结果。 高效性: HarmonyOS对底层运行时环境进行了优化,使…...
Linux笔记---进程:进程等待
1. 进程等待的概念 进程等待是指父进程通过系统调用wait或waitpid来对子进程进行状态检测与回收的功能。 当子进程退出时,如果父进程不读取子进程的退出状态,子进程就会成为僵尸进程,造成内存泄漏的问题。因此,父进程需要调用wa…...
【Linux】匿名管道通信场景——进程池
🔥 个人主页:大耳朵土土垚 🔥 所属专栏:Linux系统编程 这里将会不定期更新有关Linux的内容,欢迎大家点赞,收藏,评论🥳🥳🎉🎉🎉 文章目…...
算法妙妙屋-------1.递归的深邃回响:全排列的奇妙组合
全排列的简要总结 全排列(Permutation)是数学中一个经典的问题,指的是从一组元素中,将所有元素按任意顺序排列形成的所有可能序列。 特点 输入条件: 给定一组互异的元素(通常为数组或字符串)。…...
【maven-6】Maven 生命周期相关命令演示
Maven 是一个广泛使用的项目管理工具,尤其在 Java 项目中。它通过定义一系列的生命周期阶段(Phases)来管理项目的构建过程。理解这些生命周期阶段及其相关命令,对于高效地构建和管理项目至关重要。本文将通过实际演示,…...
黑马程序员Java笔记整理(day06)
1.继承的特点 2.继承的权限 3. 4.小结 5.方法重写 6.子类构造器 7.兄弟构造器 8.多态 9.小结...
LeetCode【代码随想录】刷题(动态规划篇)
509. 斐波那契数 力扣题目链接 题目:斐波那契数(通常用F(n)表示)形成的序列称为斐波那契数列 。该数列由0和1开始,后面的每一项数字都是前面两项数字的和。也就是: F(0) 0,F(1) 1 F(n) F(n - 1) F(n…...
【看海的算法日记✨优选篇✨】第三回:二分之妙,寻径中道
🎬 个人主页:谁在夜里看海. 📖 个人专栏:《C系列》《Linux系列》《算法系列》 ⛰️ 一念既出,万山无阻 目录 📖一、算法思想 细节问题 📚左右临界 📚中点选择 📚…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
Windows安装Miniconda
一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...
Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)
引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...
GO协程(Goroutine)问题总结
在使用Go语言来编写代码时,遇到的一些问题总结一下 [参考文档]:https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现: 今天在看到这个教程的时候,在自己的电…...
Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)
引言 工欲善其事,必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后,我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集,就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...
