目录

  • 一,3566. 等积子集的划分方案
  • 二,3567. 子矩阵的最小绝对差
  • 三,3568. 清理教室的最少移动
  • 四,3569. 分割数组后不同质数的最大数目

一,3566. 等积子集的划分方案

题目列表
在这里插入图片描述
本题有两种做法,dfs 选或不选 / 枚举子集,代码如下:

// dfs 选或不选
class Solution {public boolean checkEqualPartitions(int[] nums, long target) {return dfs(0, 1, 1, nums, target);}boolean dfs(int i, long mul1, long mul2, int[] nums, long target){if(mul1 > target || mul2 > target){return false;}if(i == nums.length){return mul1 == mul2 && mul1 == target;} return dfs(i+1, mul1 * nums[i], mul2, nums, target)|| dfs(i+1, mul1, mul2 * nums[i], nums, target);}
}// 枚举子集
class Solution {public boolean checkEqualPartitions(int[] nums, long target) {int n = nums.length;for(int i = 0; i < 1 << n; i++){long mul1 = 1, mul2 = 1;for(int j = 0; j < n; j++){if((i >> j & 1) == 0){mul1 *= nums[j];}else{mul2 *= nums[j];}if(mul1 > target || mul2 > target)break;}if(mul1 == mul2 && mul1 == target) return true;}return false;}
}

二,3567. 子矩阵的最小绝对差

题目列表
在这里插入图片描述
本题数据范围较小,直接暴力枚举每个 k * k 的矩阵,代码如下:

class Solution {public int[][] minAbsDiff(int[][] grid, int k) {int m = grid.length;int n = grid[0].length;int[][] ans = new int[m-k+1][n-k+1];for(int i = 0; i < m - k + 1; i++){for(int j = 0; j < n - k + 1; j++){List<Integer> lst = new ArrayList<>();for(int a = 0; a < k; a++){for(int b = 0; b < k; b++){lst.add(grid[i+a][j+b]);}}Collections.sort(lst);int res = Integer.MAX_VALUE;for(int p = 1; p < lst.size(); p++){int x = lst.get(p) - lst.get(p-1);if(x == 0) continue;res = Math.min(res, x);}ans[i][j] = res == Integer.MAX_VALUE ? 0 : res;}}return ans;}
}

三,3568. 清理教室的最少移动

题目列表
在这里插入图片描述
本题是一个 BFS 广度优先搜索问题,只不过多了两个变量 —— 垃圾(L)、能量(energy),对于本题来说,在使用 BFS 搜索的时候除了必须的坐标(x,y),还需要记录一下当前还剩于的能量(没有能量无法移动),以及还剩下的垃圾个数以及位置。

对于垃圾个数以及位置:

  • 由于题目限制了垃圾个数至多为 10 个,可以使用二进制集合来表示当前还有哪些垃圾没有处理
  • 对于垃圾所在的位置则可以额外使用一个 hashmap / 二维数组 来存储
  • 举个例子,有 3 个垃圾,分别在(1,2),(3,3),(4,3),将它们表示成二进制集合 mask = 111,使用 hashmap 存储:{(1,2):0},{(2,3):1},{(4,3),2}

综上所述,在 BFS 遍历时需要存储 4 个变量 (x,y,energy,mask),由于本题可以上下左右访问,可能会出现重复访问的情况,所以还需要一个四维布尔数组标记已经访问的位置。

优化:可以将 energy 这个维度给优化掉,贪心的想,对于 (x,y,mask) 这个状态来说,肯定是 energy 越多越好,这样可以走的更远。实际上避免在两个相邻位置之间反复横跳,避免无意义地消耗能量。

代码如下:

// 未优化代码
class Solution {public int minMoves(String[] classroom, int energy) {int n = classroom.length;int m = classroom[0].length();char[][] s = new char[n][m];int[] start = new int[2];Map<Integer, Integer> map = new HashMap<>();for(int i = 0; i < n; i++){s[i] = classroom[i].toCharArray();for(int j = 0; j < m; j++){if(s[i][j] == 'S'){start[0] = i;start[1] = j;}else if(s[i][j] == 'L'){int t = map.size(); map.put(i*20+j, t);}} }Queue<int[]> que = new LinkedList<>();int total = map.size();que.offer(new int[]{start[0], start[1], energy, (1 << total) - 1});boolean[][][][] vis = new boolean[n][m][energy+1][1<<total];vis[start[0]][start[1]][energy][(1<<total)-1] = true;int[][] dirct = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};for(int ans = 0; !que.isEmpty(); ans++){int size = que.size();while(size-- > 0){int[] t = que.poll();int i = t[0], j = t[1], e = t[2], mask = t[3];if(mask == 0) return ans;if(e == 0) continue;for(int[] d : dirct){int x = i + d[0];int y = j + d[1];if(x >= 0 && x < n && y >= 0 && y < m && s[x][y] != 'X'){int newE = s[x][y] == 'R' ? energy : e - 1;int idx = map.getOrDefault(x*20+y, -1);int newMask = idx >= 0 ? mask & ~(1<<idx) : mask;if(!vis[x][y][newE][newMask]){vis[x][y][newE][newMask] = true;que.add(new int[]{x, y, newE, newMask});}} }}}return -1;}
}// 优化代码
class Solution {public int minMoves(String[] classroom, int energy) {int n = classroom.length;int m = classroom[0].length();int[] start = new int[2]; // 记录初始位置Map<Integer, Integer> map = new HashMap<>();for(int i = 0; i < n; i++){for(int j = 0; j < m; j++){if(classroom[i].charAt(j) == 'S'){start[0] = i;start[1] = j;}else if(classroom[i].charAt(j) == 'L'){int t = map.size(); map.put(i*20+j, t); // 记录 (x,y) : i}} }Queue<int[]> que = new LinkedList<>();int total = map.size();que.offer(new int[]{start[0], start[1], energy, (1 << total) - 1});byte[][][] maxEnergy = new byte[n][m][1<<total];for(byte[][] x : maxEnergy){for(byte[] y : x){Arrays.fill(y, (byte)-1);}}maxEnergy[start[0]][start[1]][(1<<total)-1] = (byte)energy;int[][] dirct = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};for(int ans = 0; !que.isEmpty(); ans++){int size = que.size();while(size-- > 0){int[] t = que.poll();int i = t[0], j = t[1], e = t[2], mask = t[3];if(mask == 0) return ans; // 垃圾捡完了,直接返回if(e == 0) continue; // 能量用完了,无法移动for(int[] d : dirct){int x = i + d[0];int y = j + d[1];if(x >= 0 && x < n && y >= 0 && y < m && classroom[x].charAt(y)  != 'X'){byte newE = (byte)(classroom[x].charAt(y) == 'R' ? energy : e - 1);int idx = map.getOrDefault(x*20+y, -1);int newMask = idx >= 0 ? mask & ~(1<<idx) : mask;if(maxEnergy[x][y][newMask] < newE){// 更新状态maxEnergy[x][y][newMask] = newE;que.add(new int[]{x, y, newE, newMask});}} }}}return -1;}
}

四,3569. 分割数组后不同质数的最大数目

题目列表
在这里插入图片描述
本题明面上是一个前后缀的问题,实际上是一个区间更新+区间查询的题,将每次查询的答案分成两个部分,一部分是 nums 数组中所有不同质数的个数,另一部分则是分割后能多出来的质数个数。第二个部分画个图来理解一下:
在这里插入图片描述
根据上述图像可以发现,我们需要维护每个质数第一次出现的位置以及最后一次出现的位置,所有可以使用 TreeSet 有序集合来维护,又因为不只一个质数,所以还需要嵌套一个哈希表,即需要使用Map<Integer, TreeSet<Integer>> 这个数据结构。 而区间更新 + 区间查询则是使用Lazy线段树来实现。

代码如下:

class LazySegmentTree{// 懒标记初始值private static final int TODO_INIT = 0;private static final class Node{int val;int todo;}private int mergeValue(int a, int b){return Math.max(a, b);}// 合并懒标记private int mergeTodo(int a, int b){return a + b;}// 懒标记更新private void apply(int i, int l, int r, int todo){Node cur = tree[i];cur.val += todo;cur.todo = mergeTodo(todo, cur.todo);}private final int n;private final Node[] tree;public LazySegmentTree(int n, int initVal){this.n = n;int[] a = new int[n];Arrays.fill(a, initVal);tree = new Node[n<<2];build(1, 0, n-1, a);}public LazySegmentTree(int[] a){n = a.length;tree = new Node[n<<2];build(1, 0, n-1, a);}public void update(int ql, int qr, int f){update(1, 0, n-1, ql, qr, f);}private void spread(int i, int l, int r){int todo = tree[i].todo;if(todo == TODO_INIT){return;}int m = (l + r) / 2;apply(i << 1, l, m, todo);apply(i << 1 | 1, m + 1, r, todo);tree[i].todo = TODO_INIT;}private void maintain(int node){tree[node].val = mergeValue(tree[node<<1].val, tree[node<<1|1].val);}private void build(int i, int l, int r, int[] a){tree[i] = new Node();tree[i].todo = TODO_INIT;if(l == r){tree[i].val = a[l];return;}int m = (l + r) / 2;build(i<<1, l, m, a);build(i<<1|1, m+1, r, a);maintain(i);}private void update(int i, int l, int r, int L, int R, int f){if(L <= l && r <= R){apply(i, l, r, f);return;}spread(i, l, r);int mid = (l + r) / 2;if(L <= mid){update(i<<1, l, mid, L, R, f);}if(R > mid){update(i<<1|1, mid+1, r, L, R, f);}maintain(i);}public int query(int l, int r){return query(1, 0, n-1, l, r);}private int query(int i, int l, int r, int ql, int qr){if(ql <= l && r <= qr){return tree[i].val;}spread(i, l, r);int m = (l + r) / 2;if(qr <= m){return query(i<<1, l, m, ql, qr);}if(ql > m){return query(i<<1|1, m+1, r, ql, qr);}int lRes = query(i<<1, l, m, ql, qr);int rRes = query(i<<1|1, m+1, r, ql, qr);return mergeValue(lRes, rRes);}
}
class Solution {private static final int MX = 100_000;private static final boolean[] np = new boolean[MX+1];static{np[0] = np[1] = true;for(int i = 2; i <= MX; i++){if(!np[i]){for(int j = i; j <= MX / i; j++){np[i * j] = true;}}}}public int[] maximumCount(int[] nums, int[][] queries) {int n = nums.length;Map<Integer, TreeSet<Integer>> pos = new HashMap<>();for(int i = 0; i < n; i++){if(!np[nums[i]])pos.computeIfAbsent(nums[i], e->new TreeSet<>()).add(i);}LazySegmentTree t = new LazySegmentTree(n, 0);// 初始化for(TreeSet<Integer> s : pos.values()){if(s.size() > 1){t.update(s.first(), s.last(), 1);}}int m = queries.length;int[] ans = new int[m];for(int qi = 0; qi < m; qi++){int i = queries[qi][0], v = queries[qi][1];int old = nums[i];nums[i] = v;if(!np[old]){ // 处理旧值TreeSet<Integer> s = pos.get(old);if(s.size() > 1){ // 先撤回之前的更新操作t.update(s.first(), s.last(), -1);}s.remove(i); // 删除后if(s.size() > 1){ // 再执行更新操作t.update(s.first(), s.last(), 1);}else if(s.isEmpty()){pos.remove(old);}}if(!np[v]){ // 处理更新后的值TreeSet<Integer> s = pos.computeIfAbsent(v, k->new TreeSet<>());if(s.size() > 1){// 先撤回之前的更新操作t.update(s.first(), s.last(), -1);}s.add(i);// 添加后if(s.size() > 1){// 再执行更新操作t.update(s.first(), s.last(), 1);}}// nums 中所有不同质数的个数 + 分割后能多出来的质数个数ans[qi] = pos.size() + t.query(0, n-1);}return ans;}
}

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

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

相关文章

【FAQ】HarmonyOS SDK 闭源开放能力 —Account Kit(5)

1.问题描述&#xff1a; 集成华为一键登录的LoginWithHuaweiIDButton&#xff0c; 但是Button默认名字叫 “华为账号一键登录”&#xff0c;太长无法显示&#xff0c;能否简写成“一键登录”与其他端一致&#xff1f; 解决方案&#xff1a; 问题分两个场景&#xff1a; 一、…

Asp.Net Core SignalR的分布式部署

文章目录 前言一、核心二、解决方案架构三、实现方案1.使用 Azure SignalR Service2.Redis Backplane(Redis 背板方案&#xff09;3.负载均衡配置粘性会话要求无粘性会话方案&#xff08;仅WebSockets&#xff09;完整部署示例&#xff08;Redis Docker&#xff09;性能优化技…

L2-054 三点共线 - java

L2-054 三点共线 语言时间限制内存限制代码长度限制栈限制Java (javac)2600 ms512 MB16KB8192 KBPython (python3)2000 ms256 MB16KB8192 KB其他编译器2000 ms64 MB16KB8192 KB 题目描述&#xff1a; 给定平面上 n n n 个点的坐标 ( x _ i , y _ i ) ( i 1 , ⋯ , n ) (x\_i…

【 java 基础知识 第一篇 】

目录 1.概念 1.1.java的特定有哪些&#xff1f; 1.2.java有哪些优势哪些劣势&#xff1f; 1.3.java为什么可以跨平台&#xff1f; 1.4JVM,JDK,JRE它们有什么区别&#xff1f; 1.5.编译型语言与解释型语言的区别&#xff1f; 2.数据类型 2.1.long与int类型可以互转吗&…

高效背诵英语四级范文

以下是结合认知科学和实战验证的 ​​高效背诵英语作文五步法​​&#xff0c;助你在30分钟内牢固记忆一篇作文&#xff0c;特别适配考前冲刺场景&#xff1a; &#x1f4dd; ​​一、解构作文&#xff08;5分钟&#xff09;​​ ​​拆解逻辑框架​​ 用荧光笔标出&#xff…

RHEL7安装教程

RHEL7安装教程 下载RHEL7镜像 通过网盘分享的文件&#xff1a;RHEL 7.zip 链接: https://pan.baidu.com/s/1ExLhdJigj-tcrHJxIca5XA?pwdjrrj 提取码: jrrj --来自百度网盘超级会员v6的分享安装 1.打开VMware&#xff0c;新建虚拟机&#xff0c;选择自定义然后下一步 2.点击…

结构型设计模式之Decorator(装饰器)

结构型设计模式之Decorator&#xff08;装饰器&#xff09; 前言&#xff1a; 本案例通过李四举例&#xff0c;不改变源代码的情况下 对“才艺”进行增强。 摘要&#xff1a; 摘要&#xff1a; 装饰器模式是一种结构型设计模式&#xff0c;允许动态地为对象添加功能而不改变其…

Kotlin委托机制使用方式和原理

目录 类委托属性委托简单的实现属性委托Kotlin标准库中提供的几个委托延迟属性LazyLazy委托参数可观察属性Observable委托vetoable委托属性储存在Map中 实践方式双击back退出Fragment/Activity传参ViewBinding和委托 类委托 类委托有点类似于Java中的代理模式 interface Base…

SpringBoot接入Kimi实践记录轻松上手

kimi简单使用 什么是Kimi API 官网&#xff1a;https://platform.moonshot.cn/ Kimi API 并不是一个我所熟知的广泛通用的术语。我的推测是&#xff0c;你可能想问的是关于 API 的一些基础知识。API&#xff08;Application Programming Interface&#xff0c;应用程序编程接…

书籍在其他数都出现k次的数组中找到只出现一次的数(7)0603

题目 给定一个整型数组arr和一个大于1的整数k。已知arr中只有1个数出现了1次&#xff0c;其他的数都出现了k次&#xff0c;请返回只出现了1次的数。 解答&#xff1a; 对此题进行思路转换&#xff0c;可以将此题&#xff0c;转换成k进制数。 k进制的两个数c和d&#xff0c;…

React 项目初始化与搭建指南

React 项目初始化有多种方式&#xff0c;可以选择已有的脚手架工具快速创建项目&#xff0c;也可以自定义项目结构并使用构建工具实现项目的构建打包流程。 1. 脚手架方案 1.1. Vite 通过 Vite 创建 React 项目非常简单&#xff0c;只需一行命令即可完成。Vite 的工程初始化…

大模型模型推理的成本过高,如何进行量化或蒸馏优化

在人工智能的浪潮中,大模型已经成为推动技术革新的核心引擎。从自然语言处理到图像生成,再到复杂的多模态任务,像GPT、BERT、T5这样的庞大模型展现出了惊人的能力。它们在翻译、对话系统、内容生成等领域大放异彩,甚至在医疗、金融等行业中也开始扮演重要角色。可以说,这些…

机器学习在多介质环境中多污染物空间预测的应用研究

机器学习在多介质环境中多污染物空间预测的应用研究 1. 引言 1.1 研究背景与意义 随着工业化和城市化进程加速,环境中多种污染物的共存已成为全球性环境问题。重金属(如铅、汞、镉)、有机污染物(如多环芳烃、农药残留)和新兴污染物(如微塑料、药品残留)在空气、水体、…

图解深度学习 - 激活函数和损失函数

激活函数和损失函数在深度学习中扮演着至关重要的角色。通过选择合适的激活函数和损失函数&#xff0c;可以显著提高神经网络的表达能力和优化效果。 其中激活函数是神经网络中的非线性函数&#xff0c;用于在神经元之间引入非线性关系&#xff0c;从而使模型能够学习和表示复…

影响服务器稳定性的因素都有什么?

服务器的稳定性会影响到业务是否能够持续运行&#xff0c;用户在进行访问网站的过程中是否出现页面卡顿的情况&#xff0c;本文就来了解一下都是哪些因素影响着服务器的稳定性。 服务器中的硬件设备是保证服务器稳定运行的基础&#xff0c;企业选择高性能的处理器和大容量且高速…

TopCode之最大子数组和

题目链接 53. 最大子数组和 - 力扣&#xff08;LeetCode&#xff09; 题目解析 算法原理 解法1: 暴力(一个循环用来固定,一个用来找最大的子数组O(n^2),每次往后拓展一个元素就判断是否是最长的),枚举出每一种情况, 然后不断更新最大的 解法二: dp 1> dp的含义: dp[i]记…

深入解析 Flask 命令行工具与 flask run命令的使用

Flask 是一个轻量级的 Python Web 应用框架&#xff0c;其内置的命令行工具&#xff08;CLI&#xff09;基于 Click 库&#xff0c;提供了方便的命令行接口&#xff0c;用于管理和运行 Flask 应用程序。本文将详细介绍 Flask 命令行工具的功能&#xff0c;以及如何使用 flask r…

QFramework v1.0 Guide: 工具篇——ViewControllor, ActionKit时序动作执行系统,ResKit资源管理开发解决方案

目录 一、QFramework.Toolkits简介 二、View Controllor 1、作用 2、应用场景 3、示例 三、ActionKit时序动作执行系统 1. 用法 &#xff08;1&#xff09;延时回调 &#xff08;2&#xff09;序列执行 &#xff08;3&#xff09;帧延时 &#xff08;4&#xff09;条…

GLIDE论文阅读笔记与DDPM(Diffusion model)的原理推导

Abstract 扩散模型&#xff08;Diffusion model&#xff09;最近被证明可以生成高质量的合成图像&#xff0c;尤其是当它们与某种引导技术结合使用时&#xff0c;可以在生成结果的多样性与保真度之间进行权衡。本文探讨了在文本条件图像生成任务中使用扩散模型&#xff0c;并比…

@Pushgateway 数据自动清理

文章目录 Pushgateway 数据自动清理一、Pushgateway 数据清理的必要性二、自动清理方案方案1&#xff1a;使用带TTL功能的Pushgateway分支版本方案2&#xff1a;使用Shell脚本定期清理方案3&#xff1a;结合Prometheus记录规则自动清理 三、最佳实践建议四、验证与维护五、示例…