【力扣周赛】第 360 场周赛(贪心 ⭐树上倍增)
文章目录
- 竞赛链接
- Q1:8015. 距离原点最远的点(贪心)
- Q2:8022. 找出美丽数组的最小和(贪心)
- Q3:2835. 使子序列的和等于目标的最少操作次数(贪心)
- 思路
- 竞赛时丑陋代码(有一说一没眼看,现在已经忘了当时是怎么想的了)
- 优雅代码
- Q4:2836. 在传球游戏中最大化函数值(⭐⭐⭐⭐⭐树上倍增)
- 解法——利用倍增算法
- 模板题——1483. 树节点的第 K 个祖先
- 成绩记录
竞赛链接
https://leetcode.cn/contest/weekly-contest-360
Q1:8015. 距离原点最远的点(贪心)
https://leetcode.cn/problems/furthest-point-from-origin/

提示:
1 <= moves.length == n <= 50
moves 仅由字符 'L'、'R' 和 '_' 组成
抓住本质,R 和 L 是不能改变的,而 _ 是可以随意选择的,因此可以在最后决定 _ 往哪个方向走。
class Solution {public int furthestDistanceFromOrigin(String moves) {int ans = 0, cnt = 0, pos = 0;for (char ch: moves.toCharArray()) {if (ch == 'R') pos++;else if (ch == 'L') pos--;else cnt++;}return Math.abs(pos) + cnt;}
}
Q2:8022. 找出美丽数组的最小和(贪心)
https://leetcode.cn/problems/find-the-minimum-possible-sum-of-a-beautiful-array/

提示:
1 <= n <= 10^5
1 <= target <= 10^5
这道题目和 第 359 场周赛 中的 6450. k-avoiding 数组的最小总和 几乎一样。
我们还是用贪心来解决,从小到大,能选就选。
class Solution {public long minimumPossibleSum(int n, int target) {long ans = 0;Set<Integer> s = new HashSet<>();for (int i = 1; s.size() < n; ++i) {if (!s.contains(target - i)) {s.add(i);ans += i;}}return ans;}
}
Q3:2835. 使子序列的和等于目标的最少操作次数(贪心)
https://leetcode.cn/problems/minimum-operations-to-form-subsequence-with-target-sum/

提示:
1 <= nums.length <= 1000
1 <= nums[i] <= 2^30
nums 只包含非负整数,且均为 2 的幂。
1 <= target < 2^31
思路
首先确定 sum >= target 则一定有解,否则一定无解。

竞赛时丑陋代码(有一说一没眼看,现在已经忘了当时是怎么想的了)
class Solution {static Map<Integer, Integer> m = new HashMap(), m2 = new HashMap();static {for (int i = 0, v = 1; i <= 30; ++i, v *= 2) {m.put(v, i);m2.put(i, v);}}public int minOperations(List<Integer> nums, int target) {long sum = 0;int[] cnt = new int[31], cnt2 = new int[31];for (int num: nums) {sum += num;cnt[m.get(num)]++;}if (sum < target) return -1;for (int i = 30; i >= 0; --i) {if (target >= m2.get(i)) {cnt2[i]++;target -= m2.get(i);}}int v = 0, ans = 0, last = -1;for (int i = 0; i <= 30; ++i) {if (cnt[i] > cnt2[i]) {if (last != -1) {ans += i - last;last = -1;v += (cnt[i] - cnt2[i] - 1) * m2.get(i);} else {v += (cnt[i] - cnt2[i]) * m2.get(i);}} else if (cnt[i] < cnt2[i]) {if (v >= (cnt2[i] - cnt[i]) * m2.get(i)) {v -= (cnt2[i] - cnt[i]) * m2.get(i);}else if (last == -1) last = i;}}return ans;}
}
优雅代码
https://leetcode.cn/problems/minimum-operations-to-form-subsequence-with-target-sum/solutions/2413344/tan-xin-by-endlesscheng-immn/
class Solution {public int minOperations(List<Integer> nums, int target) {long s = 0; // 求和long[] cnt = new long[31]; // 统计2^i的数量for (int x: nums) {s += x;cnt[Integer.numberOfTrailingZeros(x)]++;}if (s < target) return -1; // 无解的情况int ans = 0, i = 0;s = 0;// 注意这里是1L,因为i 最大是 30,这是可以进循环的,但是加一后就变成 31 了,虽然一定不会进入循环,但是要在 while 那里判断一下。while ((1L << i) <= target) {s += cnt[i] << i;int mask = (int) ((1L << ++i) - 1);if (s >= (target & mask)) continue; // 检查当前和能否填补target部分ans++; // 否则需要分解更大的数字while (cnt[i] == 0) {ans++;i++;}}return ans;}
}
Q4:2836. 在传球游戏中最大化函数值(⭐⭐⭐⭐⭐树上倍增)
https://leetcode.cn/problems/maximize-value-of-function-in-a-ball-passing-game/

提示:
1 <= receiver.length == n <= 10^5
0 <= receiver[i] <= n - 1
1 <= k <= 10^10
解法——利用倍增算法
利用倍增算法,预处理每个节点 x 的第 2^i个祖先节点,以及从 x 的父节点到 x 的第 2^i 个祖先节点的节点编号之和。最后枚举起点 x,一边向上跳一边累加节点编号。
可以从代码模板中修改过来,多了要维护节点之间的和。
class Solution {public long getMaxFunctionValue(List<Integer> receiver, long k) {int n = receiver.size(); // 节点的个数int m = 64 - Long.numberOfLeadingZeros(k); // k的二进制长度int[][] pa = new int[n][m]; // 节点x的第2^i个祖宗节点的变好long[][] sum = new long[n][m]; // 节点x的父节点到x的第2^i个祖宗节点的节点编号之和// 初始化dp数组for (int i = 0; i < n; ++i) {pa[i][0] = receiver.get(i);sum[i][0] = receiver.get(i);}// 递推dp数组(先枚举i,再枚举x)for (int i = 0; i < m - 1; ++i) { // 注意这里的条件是 i < m - 1for (int x = 0; x < n; ++x) {int p = pa[x][i];pa[x][i + 1] = p < 0? -1: pa[p][i];// 合并节点的和 sum[x][i + 1] = sum[x][i] + sum[p][i]; }}long ans = 0;// 枚举各个节点作为起始节点for (int i = 0; i < n; ++i) {long s = i;int x = i;for (long t = k; t > 0; t &= t - 1) {int ctz = Long.numberOfTrailingZeros(t);// 要先处理求和,再处理节点的变化s += sum[x][ctz]; x = pa[x][ctz];}ans = Math.max(ans, s);}return ans;}
}
受 cpu 缓存的影响,倍增的二维数组开成 log*n 会比 n*log 快很多。
二维数组开成 logn * n 的形状会比开成 n * logn 的形状快很多,是因为在计算机中,连续的内存访问比随机的内存访问更快。当我们按行访问一个二维数组时,我们可以利用缓存行的概念,即将一行的数据读入缓存中,这样下一次访问时就可以直接从缓存中读取数据,而不需要再次从内存中读取。如果我们按列访问二维数组,则每次访问都需要跨越多个缓存行,这样会导致缓存失效,从而降低程序的性能。因此,将二维数组按行存储可以提高程序的性能。
所以可以将代码修改成如下:
class Solution {public long getMaxFunctionValue(List<Integer> receiver, long k) {int n = receiver.size(); // 节点的个数int m = 64 - Long.numberOfLeadingZeros(k); // k的二进制长度int[][] pa = new int[m][n]; // 节点x的第2^i个祖宗节点的变好long[][] sum = new long[m][n]; // 节点x的父节点到x的第2^i个祖宗节点的节点编号之和// 初始化dp数组for (int i = 0; i < n; ++i) {pa[0][i] = receiver.get(i);sum[0][i] = receiver.get(i);}// 递推dp数组(先枚举i,再枚举x)for (int i = 0; i < m - 1; ++i) { // 注意这里的条件是 i < m - 1for (int x = 0; x < n; ++x) {int p = pa[i][x];pa[i + 1][x] = p < 0? -1: pa[i][p];// 合并节点的和 sum[i + 1][x] = sum[i][x] + sum[i][p]; }}long ans = 0;// 枚举各个节点作为起始节点for (int i = 0; i < n; ++i) {long s = i;int x = i;for (long t = k; t > 0; t &= t - 1) {int ctz = Long.numberOfTrailingZeros(t);// 要先处理求和,再处理节点的变化s += sum[ctz][x]; x = pa[ctz][x];}ans = Math.max(ans, s);}return ans;}
}
执行用时从 237ms 加速到了 65ms 。
模板题——1483. 树节点的第 K 个祖先
https://leetcode.cn/problems/kth-ancestor-of-a-tree-node/description/

提示:
1 <= k <= n <= 5 * 10^4
parent[0] == -1 表示编号为 0 的节点是根节点。
对于所有的 0 < i < n ,0 <= parent[i] < n 总成立
0 <= node < n
至多查询 5 * 10^4 次
https://leetcode.cn/problems/kth-ancestor-of-a-tree-node/solutions/2305895/mo-ban-jiang-jie-shu-shang-bei-zeng-suan-v3rw/

本质上是动态规划,记 pa[x][i] 为每个节点 x 的第 2^i 个祖先节点。(如果不存在则为 -1)。
计算方式如下:

pa[x][1] = pa[pa[x][0]][0] 的意思是,x 节点的爷爷是 x 节点的父亲的父亲。
一般的,有 pa[x][i + 1] = pa[pa[x][i]][i]。
class TreeAncestor {int[][] pa;// 使用原始数据将整个 pa 数组预处理出来public TreeAncestor(int n, int[] parent) {int m = 32 - Integer.numberOfLeadingZeros(n); // n的二进制长度pa = new int[n][m]; // 表示节点i的2^j个祖宗节点// 初始化dp数组,即填充每个节点的父亲节点for (int i = 0; i < n; ++i) {pa[i][0] = parent[i];}// 先枚举i,再枚举x// 相当于先算出所有爷爷节点,再算出所有爷爷的爷爷节点for (int i = 0; i < m - 1; i++) {for (int x = 0; x < n; ++x) {int p = pa[x][i]; // 取出x的第2^i个祖宗节点// x的第2^(i+1)个祖宗节点 等于 x的第2^i个祖宗节点的第2^i个祖宗节点pa[x][i + 1] = p < 0? -1: pa[p][i]; }}}// 取出node节点的第k个祖宗节点public int getKthAncestor(int node, int k) {// 写法1 从低位到高位枚举// int m = 32 - Integer.numberOfLeadingZeros(k); // k的二进制长度// for (int i = 0; i < m; ++i) {// if ((k >> i & 1) == 1) { // k的二进制当前位为1// node = pa[node][i];// if (node < 0) break;// }// }// return node;// 写法2 不断去掉k末尾的1for (; k != 0 && node != -1; k &= k - 1) {node = pa[node][Integer.numberOfTrailingZeros(k)];}return node;}
}/*** Your TreeAncestor object will be instantiated and called as such:* TreeAncestor obj = new TreeAncestor(n, parent);* int param_1 = obj.getKthAncestor(node,k);*/
成绩记录

最后一题实在是写不出来了。(不过还好好像大家也都写不出来)

相关文章:
【力扣周赛】第 360 场周赛(贪心 ⭐树上倍增)
文章目录 竞赛链接Q1:8015. 距离原点最远的点(贪心)Q2:8022. 找出美丽数组的最小和(贪心)Q3:2835. 使子序列的和等于目标的最少操作次数(贪心)思路竞赛时丑陋代码&#x…...
企业如何防止数据外泄——【部署智能透明加密防泄密系统】
为防止公司文件泄密,可以采取以下措施: www.drhchina.com 分部门部署:根据不同的部门需要,为不同部门用户部署灵活的加密方案。例如,对研发部、销售部、运营部的机密资料进行强制性自动加密,对普通部门的文…...
【聚类】DBCAN聚类
OPTICS是基于DBSCAN改进的一种密度聚类算法,对参数不敏感。当需要用到基于密度的聚类算法时,可以作为DBSCAN的一种替代的优化方案,以实现更优的效果。 原理 基于密度的聚类算法(1)——DBSCAN详解_dbscan聚类_root-ca…...
通过安装cpolar内网穿透在Kali上实现SSH远程连接的步骤指南
文章目录 1. 启动kali ssh 服务2. kali 安装cpolar 内网穿透3. 配置kali ssh公网地址4. 远程连接5. 固定连接SSH公网地址6. SSH固定地址连接测试 简单几步通过cpolar 内网穿透软件实现ssh 远程连接kali! 1. 启动kali ssh 服务 默认新安装的kali系统会关闭ssh 连接服务,我们通…...
UDP和TCP协议报文格式详解
在初识网络原理(初识网络原理_蜡笔小心眼子!的博客-CSDN博客)这篇博客中,我们简单的了解了一下TCP/IP五层网络模型,这篇博客将详细的学习一下五层网络模型中传输层的两个著名协议:UDP和TCP 目录 一, 传输层的作用 二, UDP 1,UDP协议的特点 2,UDP报文格式 三, TC…...
STM32+UART串口+DMA收发
目录 1、cubemax端配置 1.1 初始化配置 1.2 GPIO配置 1.3 UART配置 1.3.1 串口基础配置 1.3.2 DMA配置 2、keil端代码设计 2.1 初始化配置 2.2 DMA接收初始化配置 2.3 DMA发送配置 2.4 接收回调函数设置 2.5 回调函数内容代码编写 2.5.1 接收回调函数 2.5.2 发送回调…...
安全基础 --- js的闭包和this属性
js闭包 简介 一个函数和对其周围状态(lexical exviroment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure) 在js中,通俗来讲,…...
【C语言每日一题】08. 字符三角形
题目来源:http://noi.openjudge.cn/ch0101/08 08 字符三角形 总时间限制: 1000ms 内存限制: 65536kB 问题描述 给定一个字符,用它构造一个底边长5个字符,高3个字符的等腰字符三角形。 输入 输入只有一行, 包含一个字符。 输出…...
如何打war包,并用war包更新服务器版本
1.打包,我用的maven打包 先执行clean将已经生成的包清除掉 清除完,点package进行打包 控制台输出success,证明打包成功了 文件名.war的后缀就是生成的war包 2.将war包上传致服务器 一般会在war包加上日期版本上传至服务器 解压上传的war…...
uniApp webview 中调用底座蓝牙打印功能异常
背景: 使用uniApp, 安卓底座 webView 方式开发; 调用方式采用H5 向 底座发送消息, 底座判断消息类型, 然后连接打印机进行打印; 内容通过指令集方式传递给打印机; 过程当中发现部分标签可以正常打印, 但又有部分不行,打印机没反应, 也没有报错; 原因分析: 对比标签内容…...
Mac下安装Jmeter及其配置
一、安装JDK环境 安装方式:mac下配置JDK环境_只看不学的博客-CSDN博客 如果已安装JDK环境即可忽略该步骤,检查方式,在终端输入java -version,如果出现了java版本,即代表已经配置过JDK环境了,如下图所示: …...
js+html实现打字游戏v1
实现逻辑:设置定时器每秒刷新一次,定时器刷新多少次执行一次生成单词操作来决定单词的生成速度,例如初始单词生成速度为1,那么定时器刷新5次才生成一次单词,每个单词用span来装,每组10个单词放到div里。监听…...
Java on VS Code 8月更新|反编译器用户体验优化、新 Maven 项目工作流、代码高亮稳定性提升
作者:Nick Zhu 排版:Alan Wang 大家好,欢迎来到 Visual Studio Code for Java 的 8 月更新!在这篇博客中,我们将为您提供有关反编译器支持的更多改进。此外,我们将展示如何创建没有原型的 Maven 项目以及一…...
划分Vlan时需要注意的问题
网络部分2019年才开始学习的,在学习过程中配置了整个公司的网络,心里才有了一点把握,算是掌握了最基本的。 不会的就上网学,反正网络上什么知识都有,只要有需求就对照着学,很长时间没有学习网络了ÿ…...
【广州华锐互动】利用AR远程指导系统进行机械故障排查,实现远程虚拟信息互动
随着工业自动化和智能化的不断发展,机械故障诊断已经成为了工业生产中的重要环节。为了提高故障诊断的准确性和效率,近年来,AR(增强现实)远程协助技术逐渐应用于机械故障诊断领域。本文将探讨AR远程协助技术在机械故障…...
Spring工具类--CollectionUtils的使用
原文网址:Spring工具类--CollectionUtils的使用_IT利刃出鞘的博客-CSDN博客 简介 本文介绍Spring的CollectionUtils的使用。 CollectionUtils工具类的作用:操作Collection,比如:List、Set。 判断 方法作用static boolean is…...
Node.js 应用的御用品: Node.js 错误处理系统
开发中,有些开发者会积极寻求处理错误,力求减少开发时间,但也有些人完全忽略了错误的存在。正确处理错误不仅意味着能够轻松发现和纠正错误,而且还意味着能够为大型应用程序开发出稳健的代码库。 特别是对于 Node.js 开发人员&am…...
K210-CanMV IDE开发软件
K210-CanMV IDE开发软件 界面功能简介连接设备临时运行开机运行程序 界面功能简介 区域①菜单栏:操作文件,使用工具等。 区域②快捷按钮:区域①中的文件和编辑中部分功能的快捷方式。 区域③连接设备:连接设备和程序控制按钮。 …...
0301yarnmapredude入门-hadoop-大数据学习
文章目录 1 MapReduce概述2 YARN2.1 yarn概述2.2 yarn与MapReduce关系2.3 yarn架构2.4 辅助角色 3 MapReduce & YARN部署3.1 集群规划3.2 配置文件3.3 分发配置文件 4 体验4.1 集群启动命令介绍4.2 提交MapReduce任务到YARN执行 结语 1 MapReduce概述 分布式计算是一种计算…...
大数据课程K15——Spark的TF-IDF计算Term权重
文章作者邮箱:yugongshiye@sina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 了解Spark的TF-IDF算法概念; ⚪ 了解Spark的TF-IDF算法定义; ⚪ 了解Spark的TF-IDF算法案例; 一、TF-IDF算法概述 TF-IDF(term frequency–inverse document frequency)是一种用于信…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...
网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
